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