Skip to content

Commit 96add28

Browse files
fkjagodzinskimaciejbocianski
authored andcommitted
Tests: Drivers: TimerEvent: Add tests
1 parent dda1ebc commit 96add28

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include "mbed.h"
17+
#include "greentea-client/test_env.h"
18+
#include "unity.h"
19+
#include "utest.h"
20+
#include "drivers/TimerEvent.h"
21+
#include "hal/ticker_api.h"
22+
#include "rtos.h"
23+
24+
using namespace utest::v1;
25+
26+
#define TEST_DELAY_US 50000ULL
27+
28+
class TestTimerEvent: public TimerEvent {
29+
private:
30+
Semaphore sem;
31+
virtual void handler() {
32+
sem.release();
33+
}
34+
35+
public:
36+
TestTimerEvent() :
37+
TimerEvent(), sem(0, 1) {
38+
}
39+
40+
TestTimerEvent(const ticker_data_t *data) :
41+
TimerEvent(data), sem(0, 1) {
42+
}
43+
44+
virtual ~TestTimerEvent() {
45+
}
46+
47+
// Make these methods publicly accessible
48+
using TimerEvent::insert;
49+
using TimerEvent::insert_absolute;
50+
using TimerEvent::remove;
51+
52+
int32_t sem_wait(uint32_t millisec) {
53+
return sem.wait(millisec);
54+
}
55+
};
56+
57+
class TestTimerEventRelative: public TestTimerEvent {
58+
public:
59+
static const int32_t SEM_SLOTS_AFTER_PAST_TS_INSERTED = 0;
60+
TestTimerEventRelative() :
61+
TestTimerEvent() {
62+
}
63+
64+
TestTimerEventRelative(const ticker_data_t *data) :
65+
TestTimerEvent(data) {
66+
}
67+
68+
// Set relative timestamp of internal event to present_time + ts
69+
void set_future_timestamp(timestamp_t ts) {
70+
insert(::ticker_read(_ticker_data) + ts);
71+
}
72+
73+
void set_past_timestamp(void) {
74+
insert(::ticker_read(_ticker_data) - 1UL);
75+
}
76+
};
77+
78+
class TestTimerEventAbsolute: public TestTimerEvent {
79+
public:
80+
static const int32_t SEM_SLOTS_AFTER_PAST_TS_INSERTED = 1;
81+
TestTimerEventAbsolute() :
82+
TestTimerEvent() {
83+
}
84+
85+
TestTimerEventAbsolute(const ticker_data_t *data) :
86+
TestTimerEvent(data) {
87+
}
88+
89+
// Set absolute timestamp of internal event to present_time + ts
90+
void set_future_timestamp(us_timestamp_t ts) {
91+
insert_absolute(::ticker_read_us(_ticker_data) + ts);
92+
}
93+
94+
void set_past_timestamp(void) {
95+
insert_absolute(::ticker_read_us(_ticker_data) - 1ULL);
96+
}
97+
};
98+
99+
/** Template for tests: insert, insert_absolute
100+
*
101+
* Test insert
102+
* Given an instance of @a TimerEvent subclass
103+
* When a tiestamp is set with @a insert()
104+
* and given time elapses
105+
* Then an event handler is called
106+
*
107+
* Test insert_absolute
108+
* Given an instance of @a TimerEvent subclass
109+
* When a tiestamp is set with @a insert_absolute()
110+
* and given time elapses
111+
* Then an event handler is called
112+
*/
113+
template<typename T>
114+
void test_insert(void) {
115+
T tte;
116+
117+
tte.set_future_timestamp(TEST_DELAY_US);
118+
int32_t sem_slots = tte.sem_wait(0);
119+
TEST_ASSERT_EQUAL(0, sem_slots);
120+
121+
sem_slots = tte.sem_wait(TEST_DELAY_US / 1000 + 1);
122+
TEST_ASSERT_EQUAL(1, sem_slots);
123+
124+
tte.remove();
125+
}
126+
127+
/** Template for tests: remove
128+
*
129+
* Test remove after insert
130+
* Given an instance of @a TimerEvent subclass
131+
* When a tiestamp is set with @a insert()
132+
* and timestamp is removed before being reached
133+
* Then the event handler is never called
134+
*
135+
* Test remove after insert_absolute
136+
* Given an instance of @a TimerEvent subclass
137+
* When a tiestamp is set with @a insert_absolute()
138+
* and timestamp is removed before being reached
139+
* Then the event handler is never called
140+
*/
141+
template<typename T>
142+
void test_remove(void) {
143+
T tte;
144+
145+
tte.set_future_timestamp(TEST_DELAY_US * 2);
146+
int32_t sem_slots = tte.sem_wait(TEST_DELAY_US / 1000);
147+
TEST_ASSERT_EQUAL(0, sem_slots);
148+
tte.remove();
149+
150+
sem_slots = tte.sem_wait(TEST_DELAY_US * 2 / 1000 + 1);
151+
TEST_ASSERT_EQUAL(0, sem_slots);
152+
}
153+
154+
/** Test insert_absolute zero
155+
* Given an instance of @a TimerEvent subclass
156+
* When a timestamp of 0 us is set with @a insert_absolute()
157+
* Then an event handler is called instantly
158+
*/
159+
void test_insert_zero(void) {
160+
TestTimerEvent tte;
161+
162+
tte.insert_absolute(0ULL);
163+
int32_t sem_slots = tte.sem_wait(0);
164+
TEST_ASSERT_EQUAL(1, sem_slots);
165+
166+
tte.remove();
167+
}
168+
169+
/** Template for tests: insert, insert_absolute past timestamp
170+
*
171+
* Test insert timestamp from the past
172+
* Given an instance of @a TimerEvent subclass
173+
* When a timestamp of X us is set with @a insert()
174+
* and X is less than present_time
175+
* Then an event handler is **not** called instantly
176+
* (the event is scheduled after the ticker's overflow)
177+
*
178+
* Test insert_absolute timestamp from the past
179+
* Given an instance of @a TimerEvent subclass
180+
* When a timestamp of X us is set with @a insert_absolute()
181+
* and X is less than present_time
182+
* Then an event handler is called instantly
183+
*/
184+
template<typename T>
185+
void test_insert_past(void) {
186+
T tte;
187+
188+
tte.set_past_timestamp();
189+
int32_t sem_slots = tte.sem_wait(0);
190+
TEST_ASSERT_EQUAL(tte.SEM_SLOTS_AFTER_PAST_TS_INSERTED, sem_slots);
191+
192+
tte.remove();
193+
}
194+
195+
utest::v1::status_t test_setup(const size_t number_of_cases)
196+
{
197+
GREENTEA_SETUP(5, "default_auto");
198+
return verbose_test_setup_handler(number_of_cases);
199+
}
200+
201+
Case cases[] = {
202+
Case("Test insert", test_insert<TestTimerEventRelative>),
203+
Case("Test insert_absolute", test_insert<TestTimerEventAbsolute>),
204+
205+
Case("Test remove after insert", test_remove<TestTimerEventRelative>),
206+
Case("Test remove after insert_absolute", test_remove<TestTimerEventAbsolute>),
207+
208+
Case("Test insert_absolute zero", test_insert_zero),
209+
210+
Case("Test insert timestamp from the past", test_insert_past<TestTimerEventRelative>),
211+
Case("Test insert_absolute timestamp from the past", test_insert_past<TestTimerEventAbsolute>),
212+
};
213+
214+
Specification specification(test_setup, cases);
215+
216+
int main()
217+
{
218+
return !Harness::run(specification);
219+
}

0 commit comments

Comments
 (0)