Skip to content

Commit 33e38cc

Browse files
committed
Tests: RTOS: RtosTimer: Add tests
1 parent 4b0cf63 commit 33e38cc

File tree

1 file changed

+354
-0
lines changed
  • TESTS/mbedmicro-rtos-mbed/rtostimer

1 file changed

+354
-0
lines changed
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
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 "rtos.h"
21+
22+
using namespace utest::v1;
23+
24+
#define TEST_DELAY_MS 50
25+
#define TEST_DELAY2_MS 30
26+
#define TEST_DELAY_MS_DELTA 1
27+
#define TEST_RESTART_DELAY_MS 10
28+
29+
#if TEST_RESTART_DELAY_MS >= TEST_DELAY_MS
30+
#error invalid TEST_RESTART_DELAY_MS value
31+
#endif
32+
33+
void timer_callback(void const *arg)
34+
{
35+
Semaphore *sem = (Semaphore *) arg;
36+
sem->release();
37+
}
38+
39+
/** Test one-shot not restarted when elapsed
40+
*
41+
* Given a one-shot timer
42+
* When the timer is started
43+
* and given time elapses
44+
* Then timer stops
45+
* and elapsed time matches given delay
46+
* and timer stays stopped
47+
*/
48+
void test_oneshot_not_restarted()
49+
{
50+
Semaphore sem(1);
51+
RtosTimer timer(mbed::callback(timer_callback, (void const *) &sem), osTimerOnce);
52+
osStatus stat = timer.stop();
53+
TEST_ASSERT_EQUAL(osErrorResource, stat);
54+
55+
Timer t;
56+
sem.wait(0);
57+
stat = timer.start(TEST_DELAY_MS);
58+
t.start();
59+
TEST_ASSERT_EQUAL(osOK, stat);
60+
61+
int32_t slots = sem.wait(TEST_DELAY_MS + 1);
62+
t.stop();
63+
TEST_ASSERT_EQUAL(1, slots);
64+
TEST_ASSERT_INT_WITHIN(TEST_DELAY_MS_DELTA * 1000, TEST_DELAY_MS * 1000, t.read_us());
65+
66+
slots = sem.wait(TEST_DELAY_MS + 1);
67+
TEST_ASSERT_EQUAL(0, slots);
68+
69+
stat = timer.stop();
70+
TEST_ASSERT_EQUAL(osErrorResource, stat);
71+
}
72+
73+
/** Test periodic repeats continuously
74+
*
75+
* Given a periodic timer
76+
* When timer is started
77+
* and given time elapses
78+
* Then timer repeats its operation
79+
* When timer is stopped
80+
* Then timer stops operation
81+
*/
82+
void test_periodic_repeats()
83+
{
84+
Semaphore sem(1);
85+
RtosTimer timer(mbed::callback(timer_callback, (void const *) &sem), osTimerPeriodic);
86+
osStatus stat = timer.stop();
87+
TEST_ASSERT_EQUAL(osErrorResource, stat);
88+
89+
Timer t;
90+
sem.wait(0);
91+
stat = timer.start(TEST_DELAY_MS);
92+
t.start();
93+
TEST_ASSERT_EQUAL(osOK, stat);
94+
95+
int32_t slots = sem.wait(TEST_DELAY_MS + 1);
96+
int t1 = t.read_us();
97+
TEST_ASSERT_EQUAL(1, slots);
98+
TEST_ASSERT_INT_WITHIN(TEST_DELAY_MS_DELTA * 1000, TEST_DELAY_MS * 1000, t1);
99+
100+
slots = sem.wait(TEST_DELAY_MS + 1);
101+
t.stop();
102+
TEST_ASSERT_EQUAL(1, slots);
103+
TEST_ASSERT_INT_WITHIN(TEST_DELAY_MS_DELTA * 1000, TEST_DELAY_MS * 1000, t.read_us() - t1);
104+
105+
stat = timer.stop();
106+
TEST_ASSERT_EQUAL(osOK, stat);
107+
108+
slots = sem.wait(TEST_DELAY_MS + 1);
109+
TEST_ASSERT_EQUAL(0, slots);
110+
111+
stat = timer.stop();
112+
TEST_ASSERT_EQUAL(osErrorResource, stat);
113+
}
114+
115+
/** Test timer can be restarted
116+
*
117+
* Given a one-shot timer
118+
* When the timer is started
119+
* and @a start is called again before given time elapses
120+
* and given time elapses
121+
* Then timer stops
122+
* and elapsed time is greater than original delay
123+
*/
124+
void test_restart()
125+
{
126+
Semaphore sem(1);
127+
RtosTimer timer(mbed::callback(timer_callback, (void const *) &sem), osTimerOnce);
128+
osStatus stat = timer.stop();
129+
TEST_ASSERT_EQUAL(osErrorResource, stat);
130+
131+
Timer t;
132+
sem.wait(0);
133+
stat = timer.start(TEST_DELAY_MS);
134+
t.start();
135+
TEST_ASSERT_EQUAL(osOK, stat);
136+
137+
int32_t slots = sem.wait(TEST_RESTART_DELAY_MS);
138+
TEST_ASSERT_EQUAL(0, slots);
139+
140+
stat = timer.start(TEST_DELAY_MS);
141+
TEST_ASSERT_EQUAL(osOK, stat);
142+
143+
slots = sem.wait(TEST_DELAY_MS + 1);
144+
t.stop();
145+
TEST_ASSERT_EQUAL(1, slots);
146+
TEST_ASSERT_INT_WITHIN(TEST_DELAY_MS_DELTA * 1000, (TEST_DELAY_MS + TEST_RESTART_DELAY_MS) * 1000, t.read_us());
147+
148+
stat = timer.stop();
149+
TEST_ASSERT_EQUAL(osErrorResource, stat);
150+
}
151+
152+
/** Test timer can be started again
153+
*
154+
* Given a one-shot timer
155+
* When the timer is started
156+
* and given time elapses
157+
* Then timer stops
158+
* When the timer is started again
159+
* and given time elapses
160+
* Then timer stops again
161+
*/
162+
void test_start_again()
163+
{
164+
Semaphore sem(1);
165+
RtosTimer timer(mbed::callback(timer_callback, (void const *) &sem), osTimerOnce);
166+
osStatus stat = timer.stop();
167+
TEST_ASSERT_EQUAL(osErrorResource, stat);
168+
169+
sem.wait(0);
170+
stat = timer.start(TEST_DELAY_MS);
171+
TEST_ASSERT_EQUAL(osOK, stat);
172+
173+
int32_t slots = sem.wait(TEST_DELAY_MS + 1);
174+
TEST_ASSERT_EQUAL(1, slots);
175+
176+
stat = timer.stop();
177+
TEST_ASSERT_EQUAL(osErrorResource, stat);
178+
179+
stat = timer.start(TEST_DELAY_MS);
180+
TEST_ASSERT_EQUAL(osOK, stat);
181+
182+
slots = sem.wait(TEST_DELAY_MS + 1);
183+
TEST_ASSERT_EQUAL(1, slots);
184+
185+
stat = timer.stop();
186+
TEST_ASSERT_EQUAL(osErrorResource, stat);
187+
}
188+
189+
/** Test timer restart updates delay
190+
*
191+
* Given a one-shot timer
192+
* When the timer is started
193+
* and @a start is called again with a different delay before given time elapses
194+
* and updated delay elapses
195+
* Then timer stops
196+
* and time elapsed since the second @a start call matches updated delay
197+
*/
198+
void test_restart_updates_delay()
199+
{
200+
Semaphore sem(1);
201+
RtosTimer timer(mbed::callback(timer_callback, (void const *) &sem), osTimerOnce);
202+
osStatus stat = timer.stop();
203+
TEST_ASSERT_EQUAL(osErrorResource, stat);
204+
205+
sem.wait(0);
206+
stat = timer.start(TEST_DELAY_MS);
207+
TEST_ASSERT_EQUAL(osOK, stat);
208+
209+
int32_t slots = sem.wait(TEST_RESTART_DELAY_MS);
210+
TEST_ASSERT_EQUAL(0, slots);
211+
212+
Timer t;
213+
stat = timer.start(TEST_DELAY2_MS);
214+
t.start();
215+
TEST_ASSERT_EQUAL(osOK, stat);
216+
217+
slots = sem.wait(TEST_DELAY2_MS + 1);
218+
t.stop();
219+
TEST_ASSERT_EQUAL(1, slots);
220+
TEST_ASSERT_INT_WITHIN(TEST_DELAY_MS_DELTA * 1000, TEST_DELAY2_MS * 1000, t.read_us());
221+
222+
stat = timer.stop();
223+
TEST_ASSERT_EQUAL(osErrorResource, stat);
224+
}
225+
226+
/** Test timer is created in stopped state
227+
*
228+
* Given a one-shot timer
229+
* When the timer has not been started
230+
* Then the timer is stopped
231+
*/
232+
void test_created_stopped()
233+
{
234+
RtosTimer timer(mbed::callback(timer_callback, (void const *) NULL), osTimerOnce);
235+
osStatus stat = timer.stop();
236+
TEST_ASSERT_EQUAL(osErrorResource, stat);
237+
}
238+
239+
/** Test one-shot can be stopped
240+
*
241+
* Given a one-shot timer
242+
* When the timer is started
243+
* and timer is stopped while still running
244+
* Then timer stops operation
245+
*/
246+
void test_stop()
247+
{
248+
Semaphore sem(1);
249+
RtosTimer timer(mbed::callback(timer_callback, (void const *) &sem), osTimerOnce);
250+
osStatus stat = timer.stop();
251+
TEST_ASSERT_EQUAL(osErrorResource, stat);
252+
253+
sem.wait(0);
254+
stat = timer.start(TEST_DELAY_MS);
255+
TEST_ASSERT_EQUAL(osOK, stat);
256+
257+
int32_t slots = sem.wait(TEST_RESTART_DELAY_MS);
258+
TEST_ASSERT_EQUAL(0, slots);
259+
260+
stat = timer.stop();
261+
TEST_ASSERT_EQUAL(osOK, stat);
262+
263+
slots = sem.wait(TEST_DELAY_MS + 1);
264+
TEST_ASSERT_EQUAL(0, slots);
265+
266+
stat = timer.stop();
267+
TEST_ASSERT_EQUAL(osErrorResource, stat);
268+
}
269+
270+
/** Test timer started with infinite delay
271+
*
272+
* Given a one-shot timer
273+
* When the timer is started with @a osWaitForever delay
274+
* Then @a start return status is @a osOK
275+
*/
276+
void test_wait_forever()
277+
{
278+
RtosTimer timer(mbed::callback(timer_callback, (void const *) NULL), osTimerOnce);
279+
280+
osStatus stat = timer.start(osWaitForever);
281+
TEST_ASSERT_EQUAL(osOK, stat);
282+
283+
stat = timer.stop();
284+
TEST_ASSERT_EQUAL(osOK, stat);
285+
}
286+
287+
/** Test timer started with zero delay
288+
*
289+
* Given a one-shot timer
290+
* When the timer is started with 0 delay
291+
* Then @a start return status is @a osErrorParameter
292+
*/
293+
void test_no_wait()
294+
{
295+
RtosTimer timer(mbed::callback(timer_callback, (void const *) NULL), osTimerOnce);
296+
297+
osStatus stat = timer.start(0);
298+
TEST_ASSERT_EQUAL(osErrorParameter, stat);
299+
300+
stat = timer.stop();
301+
TEST_ASSERT_EQUAL(osErrorResource, stat);
302+
}
303+
304+
void timer_isr_call(void const *arg)
305+
{
306+
RtosTimer *timer = (RtosTimer *) arg;
307+
osStatus stat = timer->start(TEST_DELAY_MS);
308+
TEST_ASSERT_EQUAL(osErrorISR, stat);
309+
310+
stat = timer->stop();
311+
TEST_ASSERT_EQUAL(osErrorISR, stat);
312+
}
313+
314+
/** Test timer method calls from an ISR fail
315+
*
316+
* Given a one-shot timer
317+
* When a timer method is called from an ISR
318+
* Then method return status is @a osErrorISR
319+
*/
320+
void test_isr_calls_fail()
321+
{
322+
RtosTimer timer(mbed::callback(timer_callback, (void const *) NULL), osTimerOnce);
323+
324+
Ticker ticker;
325+
ticker.attach(mbed::callback(timer_isr_call, (void const *) &timer), (float) TEST_DELAY_MS / 1000.0);
326+
327+
wait_ms(TEST_DELAY_MS + 1);
328+
}
329+
330+
utest::v1::status_t test_setup(const size_t number_of_cases)
331+
{
332+
GREENTEA_SETUP(5, "default_auto");
333+
return verbose_test_setup_handler(number_of_cases);
334+
}
335+
336+
Case cases[] = {
337+
Case("Test one-shot not restarted when elapsed", test_oneshot_not_restarted),
338+
Case("Test periodic repeats continuously", test_periodic_repeats),
339+
Case("Test timer can be restarted while running", test_restart),
340+
Case("Test stopped timer can be started again", test_start_again),
341+
Case("Test restart changes timeout", test_restart_updates_delay),
342+
Case("Test can be stopped", test_stop),
343+
Case("Test timer is created in stopped state", test_created_stopped),
344+
Case("Test timer started with infinite delay", test_wait_forever),
345+
Case("Test timer started with zero delay", test_no_wait),
346+
Case("Test calls from ISR fail", test_isr_calls_fail)
347+
};
348+
349+
Specification specification(test_setup, cases);
350+
351+
int main()
352+
{
353+
return !Harness::run(specification);
354+
}

0 commit comments

Comments
 (0)