source: rtems/cpukit/include/rtems/test-info.h

Last change on this file was ee63681a, checked in by Sebastian Huber <sebastian.huber@…>, on 09/22/23 at 12:14:14

tests: Add header for RTEMS test printer

The <rtems/test-info.h> header file is required for every RTEMS test
program. Move the RTEMS test printer support to a dedicated header file
<rtems/test-printer.h>. This removes an unnecessary dependency to the
RTEMS printer support in <rtems/test-info.h>.

Tests using the RTEMS Testing Framework no longer depend on the
<rtems/printer.h>.

  • Property mode set to 100644
File size: 9.1 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSTest
7 *
8 * @brief This header file provides interfaces of the RTEMS Test Support.
9 */
10
11/*
12 * Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifndef _RTEMS_TEST_H
37#define _RTEMS_TEST_H
38
39#include <rtems.h>
40#include <rtems/score/atomic.h>
41#include <rtems/score/smpbarrier.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif /* __cplusplus */
46
47/**
48 * @defgroup RTEMSTest Test Support
49 *
50 * @ingroup RTEMSAPI
51 *
52 * @brief Test support functions.
53 *
54 * @{
55 */
56
57/**
58 * @brief Each test must define a test name string.
59 */
60extern const char rtems_test_name[];
61
62/**
63 * @brief Fatal extension for tests.
64 */
65void rtems_test_fatal_extension(
66  rtems_fatal_source source,
67  bool always_set_to_false,
68  rtems_fatal_code code
69);
70
71/**
72 * @brief Initial extension for tests.
73 */
74#define RTEMS_TEST_INITIAL_EXTENSION \
75  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, rtems_test_fatal_extension, NULL }
76
77/**
78 * @brief Test states.
79 */
80typedef enum
81{
82  RTEMS_TEST_STATE_PASS,
83  RTEMS_TEST_STATE_FAIL,
84  RTEMS_TEST_STATE_USER_INPUT,
85  RTEMS_TEST_STATE_INDETERMINATE,
86  RTEMS_TEST_STATE_BENCHMARK
87} RTEMS_TEST_STATE;
88
89#if (TEST_STATE_EXPECTED_FAIL && TEST_STATE_USER_INPUT) || \
90    (TEST_STATE_EXPECTED_FAIL && TEST_STATE_INDETERMINATE) || \
91    (TEST_STATE_EXPECTED_FAIL && TEST_STATE_BENCHMARK) || \
92    (TEST_STATE_USER_INPUT    && TEST_STATE_INDETERMINATE) || \
93    (TEST_STATE_USER_INPUT    && TEST_STATE_BENCHMARK) || \
94    (TEST_STATE_INDETERMINATE && TEST_STATE_BENCHMARK)
95  #error Test states must be unique
96#endif
97
98#if TEST_STATE_EXPECTED_FAIL
99  #define TEST_STATE RTEMS_TEST_STATE_FAIL
100#elif TEST_STATE_USER_INPUT
101  #define TEST_STATE RTEMS_TEST_STATE_USER_INPUT
102#elif TEST_STATE_INDETERMINATE
103  #define TEST_STATE RTEMS_TEST_STATE_INDETERMINATE
104#elif TEST_STATE_BENCHMARK
105  #define TEST_STATE RTEMS_TEST_STATE_BENCHMARK
106#else
107  #define TEST_STATE RTEMS_TEST_STATE_PASS
108#endif
109
110/**
111 * @brief Prints a begin of test message using printf().
112 *
113 * @return As specified by printf().
114 */
115int rtems_test_begin(const char* name, const RTEMS_TEST_STATE state);
116
117/**
118 * @brief Prints an end of test message using printf().
119 *
120 * @return As specified by printf().
121 */
122int rtems_test_end(const char* name);
123
124/**
125 * @brief Exit the test without calling exit() since it closes stdin, etc and
126 * pulls in stdio code
127 */
128RTEMS_NO_RETURN void rtems_test_exit(int status);
129
130#define RTEMS_TEST_PARALLEL_PROCESSOR_MAX 32
131
132typedef struct rtems_test_parallel_job rtems_test_parallel_job;
133
134/**
135 * @brief Internal context for parallel job execution.
136 */
137typedef struct {
138  Atomic_Ulong stop;
139  SMP_barrier_Control barrier;
140  size_t worker_count;
141  rtems_id worker_ids[RTEMS_TEST_PARALLEL_PROCESSOR_MAX];
142  rtems_id stop_worker_timer_id;
143  const struct rtems_test_parallel_job *jobs;
144  size_t job_count;
145} rtems_test_parallel_context;
146
147/**
148 * @brief Worker task setup handler.
149 *
150 * Called during rtems_test_parallel() to optionally setup a worker task before
151 * it is started.
152 *
153 * @param[in] ctx The parallel context.
154 * @param[in] worker_index The worker index.
155 * @param[in] worker_id The worker task identifier.
156 */
157typedef void (*rtems_test_parallel_worker_setup)(
158  rtems_test_parallel_context *ctx,
159  size_t worker_index,
160  rtems_id worker_id
161);
162
163/**
164 * @brief Basic parallel job description.
165 */
166struct rtems_test_parallel_job {
167  /**
168   * @brief Job initialization handler.
169   *
170   * This handler executes only in the context of the master worker before the
171   * job body handler.
172   *
173   * @param[in] ctx The parallel context.
174   * @param[in] arg The user specified argument.
175   * @param[in] active_workers Count of active workers.  Depends on the cascade
176   *   option.
177   *
178   * @return The desired job body execution time in clock ticks.  See
179   *   rtems_test_parallel_stop_job().
180   */
181  rtems_interval (*init)(
182    rtems_test_parallel_context *ctx,
183    void *arg,
184    size_t active_workers
185  );
186
187  /**
188   * @brief Job body handler.
189   *
190   * @param[in] ctx The parallel context.
191   * @param[in] arg The user specified argument.
192   * @param[in] active_workers Count of active workers.  Depends on the cascade
193   *   option.
194   * @param[in] worker_index The worker index.  It ranges from 0 to the
195   *   processor count minus one.
196   */
197  void (*body)(
198    rtems_test_parallel_context *ctx,
199    void *arg,
200    size_t active_workers,
201    size_t worker_index
202  );
203
204  /**
205   * @brief Job finalization handler.
206   *
207   * This handler executes only in the context of the master worker after the
208   * job body handler.
209   *
210   * @param[in] ctx The parallel context.
211   * @param[in] arg The user specified argument.
212   * @param[in] active_workers Count of active workers.  Depends on the cascade
213   *   option.
214   */
215  void (*fini)(
216    rtems_test_parallel_context *ctx,
217    void *arg,
218    size_t active_workers
219  );
220
221  /**
222   * @brief Job specific argument.
223   */
224  void *arg;
225
226  /**
227   * @brief Job cascading flag.
228   *
229   * This flag indicates whether the job should be executed in a cascaded
230   * manner (the job is executed on one processor first, two processors
231   * afterwards and incremented step by step until all processors are used).
232   */
233  bool cascade;
234};
235
236/**
237 * @brief Indicates if a job body should stop its work loop.
238 *
239 * @param[in] ctx The parallel context.
240 *
241 * @retval true The job body should stop its work loop and return to the caller.
242 * @retval false Otherwise.
243 */
244static inline bool rtems_test_parallel_stop_job(
245  const rtems_test_parallel_context *ctx
246)
247{
248  return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0;
249}
250
251/**
252 * @brief Indicates if a worker is the master worker.
253 *
254 * The master worker is the thread that called rtems_test_parallel().
255 *
256 * @param[in] worker_index The worker index.
257 *
258 * @retval true This is the master worker.
259 * @retval false Otherwise.
260 */
261static inline bool rtems_test_parallel_is_master_worker(size_t worker_index)
262{
263  return worker_index == 0;
264}
265
266/**
267 * @brief Returns the task identifier for a worker.
268 *
269 * @param[in] ctx The parallel context.
270 * @param[in] worker_index The worker index.
271 *
272 * @return The task identifier of the worker.
273 */
274static inline rtems_id rtems_test_parallel_get_task_id(
275  const rtems_test_parallel_context *ctx,
276  size_t worker_index
277)
278{
279  return ctx->worker_ids[worker_index];
280}
281
282/**
283 * @brief Runs a bunch of jobs in parallel on all processors of the system.
284 *
285 * The worker tasks inherit the priority of the executing task.
286 *
287 * There are SMP barriers before and after the job body.
288 *
289 * @param[in] ctx The parallel context.
290 * @param[in] worker_setup Optional handler to setup a worker task before it is
291 *   started.
292 * @param[in] jobs The table of jobs.
293 * @param[in] job_count The count of jobs in the job table.
294 */
295void rtems_test_parallel(
296  rtems_test_parallel_context *ctx,
297  rtems_test_parallel_worker_setup worker_setup,
298  const rtems_test_parallel_job *jobs,
299  size_t job_count
300);
301
302/**
303 * @brief Performs a busy loop for the specified seconds and nanoseconds based
304 * on the CPU usage of the executing thread.
305 *
306 * This function continuously reads the CPU usage of the executing thread.
307 * This operation may lead to a scheduler instance lock contention in SMP
308 * configurations.
309 *
310 * @param[in] seconds The busy seconds.
311 * @param[in] nanoseconds The busy nanoseconds.
312 */
313void rtems_test_busy_cpu_usage(time_t seconds, long nanoseconds);
314
315/**
316 * @brief Runs the test cases of the RTEMS Test Framework using a default
317 *   configuration in the context of a task.
318 *
319 * The application must provide rtems_test_name.
320 *
321 * @param arg is the task argument.
322 * @param state is the test state.
323 */
324RTEMS_NO_RETURN void rtems_test_run(
325  rtems_task_argument    arg,
326  const RTEMS_TEST_STATE state
327);
328
329/**
330 * @brief Dumps the gcov information as a base64 encoded gcfn and gcda data
331 *   stream using rtems_put_char().
332 */
333void rtems_test_gcov_dump_info( void );
334
335/** @} */
336
337#ifdef __cplusplus
338}
339#endif /* __cplusplus */
340
341#endif /* _RTEMS_TEST_H */
Note: See TracBrowser for help on using the repository browser.