rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
test.c
Go to the documentation of this file.
1/*
2 ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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
17/**
18 * @file test.c
19 * @brief Tests support code.
20 *
21 * @addtogroup test
22 * @{
23 */
24
25#include <rusefi/true_false.h>
26#include "efifeatures.h"
27
28#if EFI_PERF_METRICS
29
30#include "test.h"
31#include "testbmk.h"
32
33/*
34 * Array of all the test patterns.
35 */
36static ROMCONST struct testcase * ROMCONST *patterns[] = {
38 NULL
39};
40
42static unsigned failpoint;
43static char tokens_buffer[MAX_TOKENS];
44static char *tokp;
45
46/*
47 * Static working areas, the following areas can be used for threads or
48 * used as temporary buffers.
49 */
51
52/*
53 * Pointers to the spawned threads.
54 */
55thread_t *threads[MAX_THREADS];
56
57/*
58 * Pointers to the working areas.
59 */
60void * ROMCONST wa[5] = {test.wa.T0, test.wa.T1, test.wa.T2,
61 test.wa.T3, test.wa.T4};
62
63/*
64 * Console output.
65 */
66static BaseSequentialStream *chp;
67
68/**
69 * @brief Prints a decimal unsigned number.
70 *
71 * @param[in] n the number to be printed
72 */
73void test_printn(uint32_t n) {
74 char buf[16], *p;
75
76 if (!n)
77 chSequentialStreamPut(chp, '0');
78 else {
79 p = buf;
80 while (n)
81 *p++ = (n % 10) + '0', n /= 10;
82 while (p > buf)
83 chSequentialStreamPut(chp, *--p);
84 }
85}
86
87/**
88 * @brief Prints a line without final end-of-line.
89 *
90 * @param[in] msgp the message
91 */
92void test_print(const char *msgp) {
93
94 while (*msgp)
95 chSequentialStreamPut(chp, *msgp++);
96}
97
98/**
99 * @brief Prints a line.
100 *
101 * @param[in] msgp the message
102 */
103void test_println(const char *msgp) {
104
105 test_print(msgp);
106 chSequentialStreamWrite(chp, (const uint8_t *)"\r\n", 2);
107}
108
109/*
110 * Tokens.
111 */
112static void clear_tokens(void) {
113
115}
116
117static void print_tokens(void) {
118 char *cp = tokens_buffer;
119
120 while (cp < tokp)
121 chSequentialStreamPut(chp, *cp++);
122}
123
124/**
125 * @brief Emits a token into the tokens buffer.
126 *
127 * @param[in] token the token as a char
128 */
129void test_emit_token(char token) {
130
131 chSysLock();
132 *tokp++ = token;
133 chSysUnlock();
134}
135
136/*
137 * Assertions.
138 */
139bool _test_fail(unsigned point) {
140
141 local_fail = TRUE;
142 global_fail = TRUE;
143 failpoint = point;
144 return TRUE;
145}
146
147bool _test_assert(unsigned point, bool condition) {
148
149 if (!condition)
150 return _test_fail(point);
151 return FALSE;
152}
153
154bool _test_assert_sequence(unsigned point, char *expected) {
155 char *cp = tokens_buffer;
156 while (cp < tokp) {
157 if (*cp++ != *expected++)
158 return _test_fail(point);
159 }
160 if (*expected)
161 return _test_fail(point);
162 clear_tokens();
163 return FALSE;
164}
165
166bool _test_assert_time_window(unsigned point, systime_t start, systime_t end) {
167
168 return _test_assert(point, chTimeIsWithin(start, end));
169}
170
171/*
172 * Threads utils.
173 */
174
175/**
176 * @brief Sets a termination request in all the test-spawned threads.
177 */
179 int i;
180
181 for (i = 0; i < MAX_THREADS; i++)
182 if (threads[i])
183 chThdTerminate(threads[i]);
184}
185
186/**
187 * @brief Waits for the completion of all the test-spawned threads.
188 */
190 int i;
191
192 for (i = 0; i < MAX_THREADS; i++)
193 if (threads[i] != NULL) {
194 chThdWait(threads[i]);
195 threads[i] = NULL;
196 }
197}
198
199#if CH_DBG_THREADS_PROFILING
200/**
201 * @brief CPU pulse.
202 * @note The current implementation is not totally reliable.
203 *
204 * @param[in] duration CPU pulse duration in milliseconds
205 */
206void test_cpu_pulse(unsigned duration) {
207 systime_t start, end, now;
208
209 start = chThdSelf()->p_time;
210 end = start + TIME_MS2I(duration);
211 do {
212 now = chThdSelf()->p_time;
213#if defined(SIMULATOR)
215#endif
216 }
217 while (end > start ? (now >= start) && (now < end) :
218 (now >= start) || (now < end));
219}
220#endif
221
222/**
223 * @brief Delays execution until next system time tick.
224 *
225 * @return The system time.
226 */
228
229 chThdSleep(1);
230 return chTimeNow();
231}
232
233/*
234 * Timer utils.
235 */
236
237/**
238 * @brief Set to @p TRUE when the test timer reaches its deadline.
239 */
241
242static VirtualTimer vt;
243static void tmr(void *p) {
244 (void)p;
245
246 test_timer_done = TRUE;
247}
248
249/**
250 * @brief Starts the test timer.
251 *
252 * @param[in] ms time in milliseconds
253 */
254void test_start_timer(unsigned ms) {
255
256 systime_t duration = TIME_MS2I(ms);
257 test_timer_done = FALSE;
258 chVTSet(&vt, duration, tmr, NULL);
259}
260
261/*
262 * Test suite execution.
263 */
264static void execute_test(const struct testcase *tcp) {
265 int i;
266
267 /* Initialization */
268 clear_tokens();
269 local_fail = FALSE;
270 for (i = 0; i < MAX_THREADS; i++)
271 threads[i] = NULL;
272
273 if (tcp->setup != NULL)
274 tcp->setup();
275 tcp->execute();
276 if (tcp->teardown != NULL)
277 tcp->teardown();
278
280}
281
282static void print_line(void) {
283 unsigned i;
284
285 for (i = 0; i < 76; i++)
286 chSequentialStreamPut(chp, '-');
287 chSequentialStreamWrite(chp, (const uint8_t *)"\r\n", 2);
288}
289
290/**
291 * @brief Test execution thread function.
292 *
293 * @param[in] p pointer to a @p BaseChannel object for test output
294 * @return A failure boolean value.
295 */
296msg_t TestThread(void *p) {
297 int i, j;
298
299 chp = p;
300 test_println("");
301 test_println("*** ChibiOS/RT test suite");
302 test_println("***");
303 test_print("*** Kernel: ");
304 test_println(CH_KERNEL_VERSION);
305 test_print("*** Compiled: ");
306 test_println(__DATE__ " - " __TIME__);
307#ifdef CH_COMPILER_NAME
308 test_print("*** Compiler: ");
309 test_println(CH_COMPILER_NAME);
310#endif
311 test_print("*** Architecture: ");
312 test_println(CH_ARCHITECTURE_NAME);
313#ifdef CH_CORE_VARIANT_NAME
314 test_print("*** Core Variant: ");
315 test_println(CH_CORE_VARIANT_NAME);
316#endif
317#ifdef CH_PORT_INFO
318 test_print("*** Port Info: ");
319 test_println(CH_PORT_INFO);
320#endif
321#ifdef PLATFORM_NAME
322 test_print("*** Platform: ");
323 test_println(PLATFORM_NAME);
324#endif
325#ifdef BOARD_NAME
326 test_print("*** Test Board: ");
327 test_println(BOARD_NAME);
328#endif
329 test_println("");
330
331 global_fail = FALSE;
332 i = 0;
333 while (patterns[i]) {
334 j = 0;
335 while (patterns[i][j]) {
336 print_line();
337 test_print("--- Test Case ");
338 test_printn(i + 1);
339 test_print(".");
340 test_printn(j + 1);
341 test_print(" (");
342 test_print(patterns[i][j]->name);
343 test_println(")");
344#if DELAY_BETWEEN_TESTS > 0
345 chThdSleepMilliseconds(DELAY_BETWEEN_TESTS);
346#endif
347 execute_test(patterns[i][j]);
348 if (local_fail) {
349 test_print("--- Result: FAILURE (#");
351 test_print(" [");
352 print_tokens();
353 test_println("])");
354 }
355 else
356 test_println("--- Result: SUCCESS");
357 j++;
358 }
359 i++;
360 }
361 print_line();
362 test_println("");
363 test_print("Final result: ");
364 if (global_fail)
365 test_println("FAILURE");
366 else
367 test_println("SUCCESS");
368
369 return (msg_t)global_fail;
370}
371
372/** @} */
373#endif /* EFI_PERF_METRICS */
void ChkIntSources(void)
bool _test_fail(unsigned point)
Definition test.c:139
static char tokens_buffer[MAX_TOKENS]
Definition test.c:43
static void execute_test(const struct testcase *tcp)
Definition test.c:264
void test_wait_threads(void)
Waits for the completion of all the test-spawned threads.
Definition test.c:189
void test_printn(uint32_t n)
Prints a decimal unsigned number.
Definition test.c:73
msg_t TestThread(void *p)
Test execution thread function.
Definition test.c:296
bool _test_assert_sequence(unsigned point, char *expected)
Definition test.c:154
union test_buffers test
Definition test.c:50
static BaseSequentialStream * chp
Definition test.c:66
thread_t * threads[MAX_THREADS]
Definition test.c:55
static void print_line(void)
Definition test.c:282
static void clear_tokens(void)
Definition test.c:112
static VirtualTimer vt
Definition test.c:242
void test_cpu_pulse(unsigned duration)
CPU pulse.
Definition test.c:206
void test_terminate_threads(void)
Sets a termination request in all the test-spawned threads.
Definition test.c:178
static bool global_fail
Definition test.c:41
static void tmr(void *p)
Definition test.c:243
void *ROMCONST wa[5]
Definition test.c:60
static void print_tokens(void)
Definition test.c:117
void test_emit_token(char token)
Emits a token into the tokens buffer.
Definition test.c:129
systime_t test_wait_tick(void)
Delays execution until next system time tick.
Definition test.c:227
static ROMCONST struct testcase *ROMCONST * patterns[]
Definition test.c:36
static bool local_fail
Definition test.c:41
void test_start_timer(unsigned ms)
Starts the test timer.
Definition test.c:254
bool _test_assert(unsigned point, bool condition)
Definition test.c:147
void test_print(const char *msgp)
Prints a line without final end-of-line.
Definition test.c:92
bool test_timer_done
Set to TRUE when the test timer reaches its deadline.
Definition test.c:240
bool _test_assert_time_window(unsigned point, systime_t start, systime_t end)
Definition test.c:166
void test_println(const char *msgp)
Prints a line.
Definition test.c:103
static char * tokp
Definition test.c:44
static unsigned failpoint
Definition test.c:42
Structure representing a test case.
Definition test.h:58
void(* execute)(void)
Test case execution function.
Definition test.h:62
void(* setup)(void)
Test case preparation function.
Definition test.h:60
void(* teardown)(void)
Test case clean up function.
Definition test.h:61
Tests support header.
ROMCONST struct testcase *ROMCONST patternbmk[]
Test sequence for benchmarks.
Definition testbmk.c:700
Kernel Benchmarks header file.
struct test_buffers::@28 wa