Merge pull request #5201 from maciejbocianski/critical_section_tests

Test set for critical section
pull/5927/head
Cruz Monrreal 2018-01-24 11:29:45 -06:00 committed by GitHub
commit 98611c8578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 230 additions and 0 deletions

View File

@ -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);
}