Skip to content

Commit 60ffd22

Browse files
committed
Add unit tests
1 parent f076516 commit 60ffd22

File tree

5 files changed

+179
-8
lines changed

5 files changed

+179
-8
lines changed

.github/workflows/c-cpp.yml

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ jobs:
2020
steps:
2121
- uses: actions/checkout@v4
2222

23+
- name: Install dependencies
24+
run: |
25+
sudo apt-get update
26+
sudo apt-get install -y build-essential cmake libgtest-dev googletest
27+
2328
- name: Create build directory
2429
run: mkdir build
2530

@@ -28,3 +33,7 @@ jobs:
2833

2934
- name: Build
3035
run: cmake --build ${{github.workspace}}/build
36+
37+
- name: Run Unit Tests
38+
working-directory: ${{github.workspace}}/build
39+
run: ./test/flexitimerTest

CMakeLists.txt

+7-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
# Copyright (c) 2010 Eray Ozturk <erayozturk1@gmail.com>
44
#
55
cmake_minimum_required(VERSION 3.10)
6-
7-
project(FlexiTimerLibrary)
6+
project(FlexiTimerLibrary LANGUAGES C CXX)
87

98
# Add the include directory
109
include_directories(${PROJECT_SOURCE_DIR}/include)
@@ -13,4 +12,9 @@ include_directories(${PROJECT_SOURCE_DIR}/include)
1312
add_library(flexitimer STATIC src/flexitimer.c)
1413

1514
# Add the examples subdirectory
16-
add_subdirectory(examples)
15+
add_subdirectory(examples)
16+
17+
# Add the unit tests
18+
enable_testing()
19+
find_package(GTest REQUIRED)
20+
add_subdirectory(test)

README.md

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
# FlexiTimer Scheduler Library
1+
# FlexiTimer Scheduler Library [![Awesome](https://awesome.re/badge.svg)](https://github.com/diffstorm/flexitimer)
22

33
[![Build Status](https://github.com/diffstorm/flexitimer/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/diffstorm/flexitimer/actions)
44
[![License](https://img.shields.io/github/license/diffstorm/flexitimer)](https://github.com/diffstorm/flexitimer/blob/main/LICENSE)
55
[![Language](https://img.shields.io/github/languages/top/diffstorm/flexitimer)](https://github.com/diffstorm/flexitimer)
6+
![GitHub Stars](https://img.shields.io/github/stars/diffstorm/flexitimer?style=social)
7+
![Platforms](https://img.shields.io/badge/Platform-Linux%20%7C%20Windows%20%7C%20macOS-lightgrey)
68

7-
A fast and efficient software timer library designed to work seamlessly across any embedded system, operating system, or bare-metal environment. With MISRA C compliance, it ensures safety and reliability, making it ideal for real-time applications. The timer resolution is flexible and depends on the frequency of the handler function calls, providing high precision for various use cases.
9+
A fast and efficient software timer library designed to work seamlessly across any embedded system, operating system, or bare-metal environment. With full test coverage and MISRA C compliance, it ensures safety and reliability, making it ideal for real-time applications. The timer resolution is flexible and depends on the frequency of handler function calls, providing high precision for diverse use cases.
810

911
## Features
1012

11-
- **Lightweight and Fast**: Optimized for minimal resource usage.
12-
- **Platform Independent**: Can be used in any embedded system, OS, or bare-metal system.
13+
- **Lightweight & Fast**: Optimized for minimal resource usage.
14+
- **Platform-Independent**: Compatible with embedded systems, operating systems, and bare-metal environments.
15+
- **MISRA-Compliant**: Follows MISRA C guidelines for safety and reliability.
1316
- **Flexible Timer Resolution**: The resolution of the software timers depends on the calling frequency of the handler function.
14-
- **MISRA Compliant**: Follows MISRA C guidelines for safety and reliability.
17+
- **Industry-Proven**: Deployed in diverse industrial applications and rigorously unit-tested.
1518

1619
## Getting Started
1720

@@ -48,6 +51,12 @@ A fast and efficient software timer library designed to work seamlessly across a
4851
make
4952
```
5053

54+
5. **Run the unit tests:**
55+
56+
```bash
57+
./test/flexitimerTest
58+
```
59+
5160
### Library Usage
5261

5362
Include the library header in your project:

test/CMakeLists.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
set(CMAKE_CXX_STANDARD 11)
2+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
3+
4+
add_executable(flexitimerTest flexitimerTest.cpp)
5+
target_link_libraries(
6+
flexitimerTest
7+
PRIVATE
8+
flexitimer
9+
GTest::GTest
10+
GTest::Main
11+
)
12+
13+
include(GoogleTest)
14+
gtest_discover_tests(flexitimerTest)

test/flexitimerTest.cpp

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#include <gtest/gtest.h>
2+
#include "flexitimer.h"
3+
4+
extern "C" {
5+
static int callback_count = 0;
6+
void test_callback(timer_id_t id)
7+
{
8+
callback_count++;
9+
}
10+
}
11+
12+
class FlexiTimerTest : public ::testing::Test
13+
{
14+
protected:
15+
void SetUp() override
16+
{
17+
flexitimer_init();
18+
callback_count = 0;
19+
}
20+
};
21+
22+
TEST_F(FlexiTimerTest, InitResetsAllTimers)
23+
{
24+
timer_state_t state;
25+
26+
for(timer_id_t i = 0; i < FLEXITIMER_MAX_TIMERS; i++)
27+
{
28+
flexitimer_get_state(i, &state);
29+
EXPECT_EQ(state, TIMER_STATE_PASSIVE);
30+
}
31+
}
32+
33+
TEST_F(FlexiTimerTest, StartValidTimer)
34+
{
35+
auto result = flexitimer_start(0, TIMER_TYPE_SINGLESHOT, 100, test_callback);
36+
EXPECT_EQ(result, FLEXITIMER_OK);
37+
}
38+
39+
TEST_F(FlexiTimerTest, StartInvalidTimerId)
40+
{
41+
auto result = flexitimer_start(FLEXITIMER_MAX_TIMERS, TIMER_TYPE_SINGLESHOT, 100, test_callback);
42+
EXPECT_EQ(result, FLEXITIMER_ERROR_INVALID_ID);
43+
}
44+
45+
TEST_F(FlexiTimerTest, PeriodicTimerZeroTimeout)
46+
{
47+
auto result = flexitimer_start(0, TIMER_TYPE_PERIODIC, 0, test_callback);
48+
EXPECT_EQ(result, FLEXITIMER_ERROR_ZERO_TIMEOUT);
49+
}
50+
51+
TEST_F(FlexiTimerTest, CallbackInvokedSingleShot)
52+
{
53+
flexitimer_start(0, TIMER_TYPE_SINGLESHOT, 1, test_callback);
54+
flexitimer_handler(); // Triggers callback
55+
EXPECT_EQ(callback_count, 1);
56+
flexitimer_handler(); // No effect
57+
EXPECT_EQ(callback_count, 1);
58+
}
59+
60+
TEST_F(FlexiTimerTest, CallbackInvokedPeriodic)
61+
{
62+
flexitimer_start(0, TIMER_TYPE_PERIODIC, 1, test_callback);
63+
flexitimer_handler(); // Triggers callback
64+
EXPECT_EQ(callback_count, 1);
65+
flexitimer_handler(); // Triggers again
66+
EXPECT_EQ(callback_count, 2);
67+
}
68+
69+
TEST_F(FlexiTimerTest, DelayActiveTimer)
70+
{
71+
flexitimer_start(0, TIMER_TYPE_SINGLESHOT, 3, nullptr);
72+
EXPECT_EQ(flexitimer_delay(0, 2), FLEXITIMER_OK);
73+
timer_time_t remaining;
74+
flexitimer_get_elapsed(0, &remaining);
75+
EXPECT_EQ(remaining, 5); // 3 + 2
76+
}
77+
78+
TEST_F(FlexiTimerTest, DelayInvalidState)
79+
{
80+
EXPECT_EQ(flexitimer_delay(0, 2), FLEXITIMER_ERROR_INVALID_STATE);
81+
}
82+
83+
TEST_F(FlexiTimerTest, PauseResumeTimer)
84+
{
85+
flexitimer_start(0, TIMER_TYPE_SINGLESHOT, 2, nullptr);
86+
EXPECT_EQ(flexitimer_pause(0), FLEXITIMER_OK);
87+
timer_state_t state;
88+
flexitimer_get_state(0, &state);
89+
EXPECT_EQ(state, TIMER_STATE_PAUSED);
90+
EXPECT_EQ(flexitimer_resume(0), FLEXITIMER_OK);
91+
flexitimer_get_state(0, &state);
92+
EXPECT_EQ(state, TIMER_STATE_ACTIVE);
93+
}
94+
95+
TEST_F(FlexiTimerTest, RestartTimer)
96+
{
97+
flexitimer_start(0, TIMER_TYPE_SINGLESHOT, 2, nullptr);
98+
flexitimer_handler(); // remaining=1
99+
EXPECT_EQ(flexitimer_restart(0), FLEXITIMER_OK);
100+
timer_time_t remaining;
101+
flexitimer_get_elapsed(0, &remaining);
102+
EXPECT_EQ(remaining, 2);
103+
}
104+
105+
TEST_F(FlexiTimerTest, CancelTimer)
106+
{
107+
flexitimer_start(0, TIMER_TYPE_SINGLESHOT, 1, test_callback);
108+
flexitimer_cancel(0);
109+
timer_state_t state;
110+
flexitimer_get_state(0, &state);
111+
EXPECT_EQ(state, TIMER_STATE_PASSIVE);
112+
flexitimer_handler(); // Should not trigger callback
113+
EXPECT_EQ(callback_count, 0);
114+
}
115+
116+
TEST_F(FlexiTimerTest, GetFunctionsWithNullArg)
117+
{
118+
EXPECT_EQ(flexitimer_get_state(0, nullptr), FLEXITIMER_ERROR_INVALID_ARG);
119+
EXPECT_EQ(flexitimer_get_type(0, nullptr), FLEXITIMER_ERROR_INVALID_ARG);
120+
EXPECT_EQ(flexitimer_get_time(0, nullptr), FLEXITIMER_ERROR_INVALID_ARG);
121+
EXPECT_EQ(flexitimer_get_elapsed(0, nullptr), FLEXITIMER_ERROR_INVALID_ARG);
122+
}
123+
124+
TEST_F(FlexiTimerTest, MultipleTimersIndependent)
125+
{
126+
flexitimer_start(0, TIMER_TYPE_SINGLESHOT, 1, test_callback);
127+
flexitimer_start(1, TIMER_TYPE_PERIODIC, 2, test_callback);
128+
flexitimer_handler(); // Timer 0 triggers, Timer 1 decrements to 1
129+
EXPECT_EQ(callback_count, 1);
130+
flexitimer_handler(); // Timer 1 triggers, count=2
131+
EXPECT_EQ(callback_count, 2);
132+
flexitimer_handler(); // Timer 1 decrements to 1
133+
flexitimer_handler(); // Timer 1 triggers, count=3
134+
EXPECT_EQ(callback_count, 3);
135+
}

0 commit comments

Comments
 (0)