mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #5201 from maciejbocianski/critical_section_tests
Test set for critical sectionpull/5927/head
commit
98611c8578
|
@ -0,0 +1,230 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest/utest.h"
|
||||
|
||||
|
||||
using utest::v1::Case;
|
||||
|
||||
|
||||
volatile bool callback_called;
|
||||
|
||||
void tiemout_callback(void)
|
||||
{
|
||||
callback_called = true;
|
||||
}
|
||||
|
||||
template<int N>
|
||||
void critical_section_raii_recursive(Timeout &timeout)
|
||||
{
|
||||
static uint32_t depth = 0;
|
||||
CriticalSectionLock cs;
|
||||
|
||||
depth++;
|
||||
TEST_ASSERT_TRUE(core_util_in_critical_section());
|
||||
|
||||
if(depth < N) {
|
||||
critical_section_raii_recursive<N>(timeout);
|
||||
} else {
|
||||
// max depth reached - do the test
|
||||
const us_timestamp_t timeout_time_us = 1;
|
||||
const int wait_time_us = timeout_time_us * 100;
|
||||
|
||||
timeout.attach_us(callback(tiemout_callback), timeout_time_us);
|
||||
wait_us(wait_time_us);
|
||||
}
|
||||
TEST_ASSERT_TRUE(core_util_in_critical_section());
|
||||
TEST_ASSERT_FALSE(callback_called);
|
||||
}
|
||||
|
||||
|
||||
/** Template for tests
|
||||
|
||||
Test C API of critical section
|
||||
Given a Timeout with callback attached
|
||||
When before critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
When inside critical section
|
||||
Then interrupts are disabled and timeout callback is blocked
|
||||
When after critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
|
||||
Test C API of critical section - nested lock
|
||||
Given a Timeout with callback attached
|
||||
When before critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
When inside nested critical section
|
||||
Then interrupts are disabled and timeout callback is blocked
|
||||
When after critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
*/
|
||||
template<int N>
|
||||
void test_C_API(void)
|
||||
{
|
||||
Timeout timeout;
|
||||
const us_timestamp_t timeout_time_us = 1;
|
||||
const int wait_time_us = timeout_time_us * 100;
|
||||
|
||||
TEST_ASSERT_FALSE(core_util_in_critical_section());
|
||||
|
||||
callback_called = false;
|
||||
timeout.attach_us(callback(tiemout_callback), timeout_time_us);
|
||||
wait_us(wait_time_us);
|
||||
TEST_ASSERT_TRUE(callback_called);
|
||||
|
||||
for(int i = 0; i < N; i++) {
|
||||
core_util_critical_section_enter();
|
||||
TEST_ASSERT_TRUE(core_util_in_critical_section());
|
||||
}
|
||||
|
||||
callback_called = false;
|
||||
timeout.attach_us(callback(tiemout_callback), timeout_time_us);
|
||||
wait_us(wait_time_us);
|
||||
TEST_ASSERT_FALSE(callback_called);
|
||||
TEST_ASSERT_TRUE(core_util_in_critical_section());
|
||||
|
||||
for(int i = 0; i < N - 1; i++) {
|
||||
core_util_critical_section_exit();
|
||||
TEST_ASSERT_TRUE(core_util_in_critical_section());
|
||||
TEST_ASSERT_FALSE(callback_called);
|
||||
}
|
||||
|
||||
core_util_critical_section_exit();
|
||||
TEST_ASSERT_FALSE(core_util_in_critical_section());
|
||||
TEST_ASSERT_TRUE(callback_called);
|
||||
}
|
||||
|
||||
/** Template for tests
|
||||
|
||||
Test C++ API of critical section constructor/destructor
|
||||
Given a Timeout with callback attached
|
||||
When before critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
When inside critical section
|
||||
Then interrupts are disabled and timeout callback is blocked
|
||||
When after critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
|
||||
Test C++ API of critical section constructor/destructor - nested lock
|
||||
Given a Timeout with callback attached
|
||||
When before critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
When inside nested critical section
|
||||
Then interrupts are disabled and timeout callback is blocked
|
||||
When after critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
*/
|
||||
template<int N>
|
||||
void test_CPP_API_constructor_destructor(void)
|
||||
{
|
||||
Timeout timeout;
|
||||
const us_timestamp_t timeout_time_us = 1;
|
||||
const int wait_time_us = timeout_time_us * 100;
|
||||
|
||||
TEST_ASSERT_FALSE(core_util_in_critical_section());
|
||||
|
||||
callback_called = false;
|
||||
timeout.attach_us(callback(tiemout_callback), timeout_time_us);
|
||||
wait_us(wait_time_us);
|
||||
TEST_ASSERT_TRUE(callback_called);
|
||||
|
||||
callback_called = false;
|
||||
critical_section_raii_recursive<N>(timeout);
|
||||
|
||||
TEST_ASSERT_FALSE(core_util_in_critical_section());
|
||||
TEST_ASSERT_TRUE(callback_called);
|
||||
}
|
||||
|
||||
/** Template for tests
|
||||
|
||||
Test C++ API of critical section enable/disable
|
||||
Given a Timeout with attached callback
|
||||
When before critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
When inside critical section
|
||||
Then interrupts are disabled and timeout callback is blocked
|
||||
When after critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
|
||||
Test C++ API of critical section enable/disable - nested lock
|
||||
Given a Timeout with attached callback
|
||||
When before critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
When inside nested critical section
|
||||
Then interrupts are disabled and timeout callback is blocked
|
||||
When after critical section
|
||||
Then interrupts are enabled and timeout callback is fired
|
||||
*/
|
||||
template<int N>
|
||||
void test_CPP_API_enable_disable(void)
|
||||
{
|
||||
Timeout timeout;
|
||||
const us_timestamp_t timeout_time_us = 1;
|
||||
const int wait_time_us = timeout_time_us * 100;
|
||||
|
||||
TEST_ASSERT_FALSE(core_util_in_critical_section());
|
||||
|
||||
callback_called = false;
|
||||
timeout.attach_us(callback(tiemout_callback), timeout_time_us);
|
||||
wait_us(wait_time_us);
|
||||
TEST_ASSERT_TRUE(callback_called);
|
||||
|
||||
for(int i = 0; i < N; i++) {
|
||||
CriticalSectionLock::enable();
|
||||
TEST_ASSERT_TRUE(core_util_in_critical_section());
|
||||
}
|
||||
|
||||
callback_called = false;
|
||||
timeout.attach_us(callback(tiemout_callback), timeout_time_us);
|
||||
wait_us(wait_time_us);
|
||||
TEST_ASSERT_FALSE(callback_called);
|
||||
TEST_ASSERT_TRUE(core_util_in_critical_section());
|
||||
|
||||
for(int i = 0; i < N - 1; i++) {
|
||||
CriticalSectionLock::disable();
|
||||
TEST_ASSERT_TRUE(core_util_in_critical_section());
|
||||
TEST_ASSERT_FALSE(callback_called);
|
||||
}
|
||||
|
||||
CriticalSectionLock::disable();
|
||||
TEST_ASSERT_FALSE(core_util_in_critical_section());
|
||||
TEST_ASSERT_TRUE(callback_called);
|
||||
}
|
||||
|
||||
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(10, "default_auto");
|
||||
return utest::v1::verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("Test critical section C API", test_C_API<1>),
|
||||
Case("Test critical section C API nested lock", test_C_API<10>),
|
||||
Case("Test critical section C++ API constructor/destructor", test_CPP_API_constructor_destructor<1>),
|
||||
Case("Test critical section C++ API constructor/destructor nested lock", test_CPP_API_constructor_destructor<10>),
|
||||
Case("Test critical section C++ API enable/disable", test_CPP_API_enable_disable<1>),
|
||||
Case("Test critical section C++ API enable/disable nested lock", test_CPP_API_enable_disable<10>)
|
||||
};
|
||||
|
||||
utest::v1::Specification specification(test_setup, cases);
|
||||
|
||||
int main()
|
||||
{
|
||||
return !utest::v1::Harness::run(specification);
|
||||
}
|
Loading…
Reference in New Issue