1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #pragma once
25
26 #include <inttypes.h>
27 #include <lk/compiler.h>
28 #include <lk/list.h>
29 #include <stdbool.h>
30 #include <string.h>
31
32 __BEGIN_CDECLS
33
34 /*
35 * This function returns a time in nanoseconds based on hardware counters
36 * it is expected to:
37 * - Be non-wrapping or have very long (years) roll-over period
38 * - Have a resolution below 100nsc
39 */
40 uint64_t get_current_time_ns(void);
41
42 /*
43 * Test functions can be defined with:
44 * TEST(SuiteName, TestName) {
45 * ... test body ...
46 * }
47 * or with:
48 * TEST_F(SuiteName, TestName) {
49 * ... test body ...
50 * }
51 * or with:
52 * TEST_P(SuiteName, TestName) {
53 * ... test body ...
54 * }
55 *
56 * NOTE: SuiteName and TestName should not contain underscores.
57 *
58 * Use EXPECT_<op> or ASSERT_<op> directly in test functions or from nested
59 * functions to check test conditions. Where <op> can be:
60 * EQ for ==
61 * NE for !=
62 * LT for <
63 * LE for <=
64 * GT for >
65 * GE for >=
66 *
67 * The test functions follows this pattern:
68 * <EXPECT|ASSERT>_<op>(val1, val2 [, format, ...])
69 * If val1 <op> val2 is not true, then both values will be printed and a test
70 * failure will be recorded. For ASSERT_<op> it will also jump to a test_abort
71 * label in the calling function.
72 *
73 * Call RUN_ALL_TESTS() to run all tests defined by TEST (or
74 * RUN_ALL_SUITE_TESTS("SuiteName") to only run tests with the specified
75 * SuiteName). RUN_ALL_TESTS and RUN_ALL_SUITE_TESTS return true if all the
76 * tests passed.
77 *
78 * Test functions defined with TEST_F or TEST_P expect the type <SuiteName>_t
79 * and <SuiteName>_SetUp and <SuiteName>_TearDown functions to be defined.
80 * The <SuiteName>_SetUp function will be called once before each test in
81 * SuiteName in run and the <SuiteName>_TearDown function will be called once
82 * after each test in SuiteName is run. These functions can be defined with
83 * TEST_F_SETUP(<SuiteName>) {
84 * ... setup body ...
85 * }
86 * and with:
87 * TEST_F_TEARDOWN(<SuiteName>) {
88 * ... teardown body ...
89 * }
90 * A pointer to a <SuiteName>_t variable will be passed as "_state" to the
91 * setup, teardown and test functions.
92 *
93 * TEST_FIXTURE_ALIAS(NewSuiteName, OldSuiteName) can be used to use the test
94 * fixture defined for OldSuiteName with NewSuiteName.
95 *
96 * Tests defined with TEST_P will only run when their suite is run if they have
97 * been instantiated with parameters using INSTANTIATE_TEST_SUITE_P. These tests
98 * can access their parameter using GetParam()
99 */
100
101 #ifndef trusty_unittest_printf
102 #error trusty_unittest_printf must be defined
103 #endif
104
105 /**
106 * struct test_context - struct representing the state of a test run.
107 * @tests_total: Number of conditions checked
108 * @tests_skipped: Number of tests skipped
109 * @tests_disabled: Number of disabled tests skipped
110 * @tests_failed: Number of conditions failed
111 * @inst_name: Name of the current parameter instantiation
112 * @suite_name: Name of the current test suite
113 * @param_name: Name of the current parameter
114 * @test_name: Name of current test case
115 * @test_param: The current test parameter
116 * @all_ok: State of current test case
117 * @skipped: Current test was skipped.
118 * @hard_fail: Type of test failure (when @all_ok is false)
119 * @test_start_time: Test Start Time in ns
120 * @suite_duration_ms:Test Suite duration in ms
121 */
122 struct test_context {
123 unsigned int tests_total;
124 unsigned int tests_skipped;
125 unsigned int tests_disabled;
126 unsigned int tests_failed;
127 const char* inst_name;
128 const char* suite_name;
129 const char* param_name;
130 const char* test_name;
131 const void* test_param;
132 bool all_ok;
133 bool skipped;
134 bool hard_fail;
135 uint64_t test_start_time;
136 uint64_t suite_duration_ms;
137 };
138
139 /**
140 * struct test_list_node - node to hold test function in list of tests
141 * @node: List node
142 * @suite: Name of test suite (optionally used for filtering)
143 * @name: Name of test (optionally used for filtering)
144 * @func: Test function
145 * @needs_param: Indicates if the test function is parameterized
146 */
147
148 struct test_list_node {
149 struct list_node node;
150 const char* suite;
151 const char* name;
152 void (*func)(void);
153 bool needs_param;
154 };
155
156 /**
157 * struct test_param_gen - struct representing a parameter generator
158 * @gen_param: Function to generate the parameter for a test
159 * @priv: Private data passed to gen_param
160 */
161 struct test_param_gen {
162 const void* (*gen_param)(void*, int);
163 void* priv;
164 };
165
166 /**
167 * typedef test_param_to_string_t - Converts a test parameter to its string form
168 * @param: Parameter to convert
169 * @buf: Buffer to fill with a NULL terminated string representation of
170 * @param
171 * @buf_size: Size in bytes of @buf
172 *
173 * When called, this function is passed a pointer to the parameter for the test
174 * that is being executed in @param and must return a null-terminated string
175 * representing the passed in parameter in @buf of at most size @buf_size.
176 */
177 typedef void (*test_param_to_string_t)(const void* param,
178 char* buf,
179 size_t buf_size);
180
181 /**
182 * struct test_param_list_node - holds parameter generators
183 * @node: List node
184 * @param_gen: Parameter generator
185 * @to_string: Function to convert a parameter to its string form
186 * @inst_name: Name of the instantiation associated with the generator
187 * @suite: Name of test suite associated with the generator
188 */
189
190 struct test_param_list_node {
191 struct list_node node;
192 struct test_param_gen param_gen;
193 test_param_to_string_t to_string;
194 const char* inst_name;
195 const char* suite;
196 };
197
198 static struct test_context _test_context;
199
200 /*
201 * List of tests. Tests are added by a __attribute__((constructor)) function
202 * per test defined by the TEST macro.
203 */
204 static struct list_node _test_list = LIST_INITIAL_VALUE(_test_list);
205
206 /*
207 * List of parameter generators. Parameter generators are added by a
208 * __attribute__((constructor)) function per instantiation defined with
209 * INSTANTIATE_TEST_SUITE_P.
210 */
211 static struct list_node _test_param_list = LIST_INITIAL_VALUE(_test_param_list);
212
trusty_unittest_print_status_name_param_duration(const char * status,const char * param_gen_inst_name,const char * suite_name,const char * test_name,const char * param_name,const char * duration_ms)213 static inline void trusty_unittest_print_status_name_param_duration(
214 const char* status,
215 const char* param_gen_inst_name, /* parameter generator instance name */
216 const char* suite_name,
217 const char* test_name,
218 const char* param_name,
219 const char* duration_ms) {
220 if (param_gen_inst_name) {
221 trusty_unittest_printf("[ %s ] %s/%s.%s/%s%s\n", status,
222 param_gen_inst_name, suite_name, test_name,
223 param_name, duration_ms);
224 } else {
225 trusty_unittest_printf("[ %s ] %s.%s%s\n", status, suite_name,
226 test_name, duration_ms);
227 }
228 }
229
trusty_unittest_print_status_name(const char * suite_name,const char * test_name,const char * status)230 static inline void trusty_unittest_print_status_name(const char* suite_name,
231 const char* test_name,
232 const char* status) {
233 trusty_unittest_print_status_name_param_duration(
234 status, _test_context.inst_name, suite_name, test_name,
235 _test_context.param_name, "");
236 }
237
trusty_unittest_print_status(const char * status)238 static inline void trusty_unittest_print_status(const char* status) {
239 trusty_unittest_print_status_name_param_duration(
240 status, _test_context.inst_name, _test_context.suite_name,
241 _test_context.test_name, _test_context.param_name, "");
242 }
243
trusty_unittest_print_status_duration(const char * status,uint64_t test_duration_ms)244 static inline void trusty_unittest_print_status_duration(
245 const char* status,
246 uint64_t test_duration_ms) {
247 char duration_str[16] = "";
248
249 /* print duration at end of test case */
250 snprintf(duration_str, sizeof(duration_str), " (%" PRIu64 " ms)",
251 test_duration_ms);
252 trusty_unittest_print_status_name_param_duration(
253 status, _test_context.inst_name, _test_context.suite_name,
254 _test_context.test_name, _test_context.param_name,
255 (const char*)duration_str);
256 }
257
TEST_BEGIN_FUNC(const char * suite_name,const char * test_name)258 static inline void TEST_BEGIN_FUNC(const char* suite_name,
259 const char* test_name) {
260 _test_context.suite_name = suite_name;
261 _test_context.test_name = test_name;
262 _test_context.all_ok = true;
263 _test_context.hard_fail = false;
264 _test_context.skipped = false;
265 _test_context.tests_total++;
266 trusty_unittest_print_status("RUN ");
267 /*
268 * initialize the test start time
269 * (after the print status is slightly better)
270 */
271 _test_context.test_start_time = get_current_time_ns();
272 }
273
TEST_END_FUNC(void)274 static inline void TEST_END_FUNC(void) {
275 uint64_t test_duration_ms =
276 (get_current_time_ns() - _test_context.test_start_time) / 1000000;
277 _test_context.suite_duration_ms += test_duration_ms;
278 if (_test_context.skipped) {
279 trusty_unittest_print_status_duration(" SKIPPED", test_duration_ms);
280 } else if (_test_context.all_ok) {
281 trusty_unittest_print_status_duration(" OK", test_duration_ms);
282 } else {
283 trusty_unittest_print_status_duration(" FAILED ", test_duration_ms);
284 }
285 _test_context.test_name = NULL;
286 }
287
288 #define STRINGIFY(x) #x
289
290 #define TEST_FIXTURE_ALIAS(new_suite_name, old_suite_name) \
291 typedef old_suite_name##_t new_suite_name##_t; \
292 \
293 static void new_suite_name##_SetUp(new_suite_name##_t* _state) { \
294 old_suite_name##_SetUp(_state); \
295 } \
296 static void new_suite_name##_TearDown(new_suite_name##_t* _state) { \
297 old_suite_name##_TearDown(_state); \
298 }
299
300 #define TEST_INTERNAL(suite_name, test_name, w_param, pre, post, arg, argp) \
301 static void suite_name##_##test_name##_inner argp; \
302 \
303 static void suite_name##_##test_name(void) { \
304 TEST_BEGIN_FUNC(STRINGIFY(suite_name), STRINGIFY(test_name)); \
305 { \
306 pre; \
307 if (!_test_context.hard_fail && !_test_context.skipped) { \
308 suite_name##_##test_name##_inner arg; \
309 } \
310 post; \
311 } \
312 TEST_END_FUNC(); \
313 } \
314 \
315 static struct test_list_node suite_name##_##test_name##_node = { \
316 .node = LIST_INITIAL_CLEARED_VALUE, \
317 .suite = #suite_name, \
318 .name = #test_name, \
319 .func = suite_name##_##test_name, \
320 .needs_param = w_param, \
321 }; \
322 \
323 __attribute__((constructor)) void suite_name##_##test_name##_add(void) { \
324 list_add_tail(&_test_list, &suite_name##_##test_name##_node.node); \
325 } \
326 \
327 static void suite_name##_##test_name##_inner argp
328
329 #define TEST_F_SETUP(suite_name) \
330 static void suite_name##_SetUp(suite_name##_t* _state)
331
332 #define TEST_F_TEARDOWN(suite_name) \
333 static void suite_name##_TearDown(suite_name##_t* _state)
334
335 #define TEST(suite_name, test_name) \
336 TEST_INTERNAL(suite_name, test_name, false, , , (), (void))
337
338 #define TEST_F_CUSTOM_ARGS(suite_name, test_name, arg, argp) \
339 TEST_INTERNAL(suite_name, test_name, false, suite_name##_t state; \
340 suite_name##_SetUp(&state);, suite_name##_TearDown(&state); \
341 , arg, argp)
342
343 #define TEST_F(suite_name, test_name) \
344 TEST_F_CUSTOM_ARGS(suite_name, test_name, (&state), \
345 (suite_name##_t * _state))
346
347 #define TEST_P_CUSTOM_ARGS(suite_name, test_name, arg, argp) \
348 TEST_INTERNAL(suite_name, test_name, true, suite_name##_t state; \
349 suite_name##_SetUp(&state);, suite_name##_TearDown(&state); \
350 , arg, argp)
351
352 #define TEST_P(suite_name, test_name) \
353 TEST_P_CUSTOM_ARGS(suite_name, test_name, (&state), \
354 (suite_name##_t * _state))
355
356 struct test_array_param {
357 const void* arr;
358 int elem_size;
359 int count;
360 };
361
test_gen_array_param(void * priv,int i)362 static inline const void* test_gen_array_param(void* priv, int i) {
363 struct test_array_param* param = (struct test_array_param*)priv;
364
365 if (i >= param->count) {
366 return NULL;
367 }
368
369 return (uint8_t*)param->arr + param->elem_size * i;
370 }
371
372 struct test_range_param {
373 long begin;
374 long end;
375 long step;
376 long current;
377 };
378
test_gen_range_param(void * priv,int i)379 static inline const void* test_gen_range_param(void* priv, int i) {
380 struct test_range_param* range_param = (struct test_range_param*)priv;
381
382 range_param->current = range_param->begin + range_param->step * i;
383
384 if (range_param->current >= range_param->end) {
385 return NULL;
386 }
387
388 return &range_param->current;
389 }
390
391 struct combined_params {
392 struct test_param_gen* generators;
393 int generator_count;
394 int* idxs;
395 const void** current;
396 };
397
update_combined_params(struct combined_params * params,int j,bool reset)398 static inline void update_combined_params(struct combined_params* params,
399 int j,
400 bool reset) {
401 if (reset) {
402 params->idxs[j] = 0;
403 }
404
405 params->current[j] = params->generators[j].gen_param(
406 params->generators[j].priv, params->idxs[j]);
407 params->idxs[j]++;
408 }
409
test_gen_combined_param(void * priv,int i)410 static inline const void* test_gen_combined_param(void* priv, int i) {
411 struct combined_params* params = (struct combined_params*)priv;
412
413 if (i == 0) {
414 for (int j = 0; j < params->generator_count; j++) {
415 update_combined_params(params, j, true);
416 }
417 return params->current;
418 }
419
420 for (int j = 0; j < params->generator_count; j++) {
421 update_combined_params(params, j, false);
422
423 if (params->current[j] != NULL) {
424 return params->current;
425 }
426
427 update_combined_params(params, j, true);
428 }
429
430 return NULL;
431 }
432
433 #define FIRST_ARG(arg0, args...) arg0
434 #define SECOND_ARG(arg0, arg1, args...) arg1
435 /* Parentheses are used to prevent commas from being interpreted when they are
436 * passed in macro arguments. DELETE_PAREN is used to remove these parentheses
437 * inside the macro that uses the commas e.g.:
438 *
439 * MY_MACRO((1, 2, 3))
440 *
441 * #define MY_MACRO(arg)
442 * DELETE_PAREN arg
443 */
444 #define DELETE_PAREN(args...) args
445
446 #define testing_Range(_begin, end_step...) \
447 (static struct test_range_param range_param = \
448 { \
449 .begin = _begin, \
450 .end = FIRST_ARG(end_step, ), \
451 .step = SECOND_ARG(end_step, 1, ), \
452 }; \
453 param_node.param_gen.gen_param = test_gen_range_param; \
454 param_node.param_gen.priv = &range_param;)
455
456 #define testing_ValuesIn(array) \
457 (static struct test_array_param array_param = \
458 { \
459 .arr = array, \
460 .elem_size = sizeof(array[0]), \
461 .count = countof(array), \
462 }; \
463 \
464 param_node.param_gen.gen_param = test_gen_array_param; \
465 param_node.param_gen.priv = &array_param;)
466
467 /*
468 * (args, args) is passed to __typeof__ to guarantee that it resolves to const
469 * char* instead of const char[] in cases where args contains a single string.
470 * When args is a single string, it is inlined and typeof will resolve to const
471 * char[].
472 */
473 #define testing_Values(args...) \
474 (static __typeof__(args, args) new_arr[] = {args}; \
475 DELETE_PAREN testing_ValuesIn(new_arr))
476
477 #define testing_Bool() testing_Values(false, true)
478
479 #define test_set_combine_params(generator, i, count) \
480 { \
481 DELETE_PAREN generator; \
482 if (i < count) { \
483 param_gens[i].gen_param = param_node.param_gen.gen_param; \
484 param_gens[i].priv = param_node.param_gen.priv; \
485 } \
486 }
487
488 #define testing_Combine_internal(arg0, arg1, arg2, arg3, arg4, arg5, arg6, \
489 arg7, arg8, arg9, da0, da1, da2, da3, da4, \
490 da5, da6, da7, da8, da9, count, args...) \
491 (static struct test_param_gen param_gens[count]; static int idxs[count]; \
492 static const void* current_params[count]; \
493 static struct combined_params combined_params = \
494 { \
495 param_gens, \
496 count, \
497 idxs, \
498 current_params, \
499 }; \
500 \
501 test_set_combine_params(arg0, 0, count); \
502 test_set_combine_params(arg1, 1, count); \
503 test_set_combine_params(arg2, 2, count); \
504 test_set_combine_params(arg3, 3, count); \
505 test_set_combine_params(arg4, 4, count); \
506 test_set_combine_params(arg5, 5, count); \
507 test_set_combine_params(arg6, 6, count); \
508 test_set_combine_params(arg7, 7, count); \
509 test_set_combine_params(arg8, 8, count); \
510 test_set_combine_params(arg9, 9, count); \
511 param_node.param_gen.gen_param = test_gen_combined_param; \
512 param_node.param_gen.priv = &combined_params;)
513
514 #define testing_Combine(generators...) \
515 testing_Combine_internal(generators, (), (), (), (), (), (), (), (), (), \
516 (), 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
517
518 #define INSTANTIATE_TEST_SUITE_P_INTERNAL(_inst_name, suite_name, param_gen, \
519 param_to_string, args...) \
520 \
521 __attribute__((constructor)) void suite_name##_##_inst_name##param_add( \
522 void) { \
523 static struct test_param_list_node param_node = { \
524 .node = LIST_INITIAL_CLEARED_VALUE, \
525 .to_string = param_to_string, \
526 .inst_name = STRINGIFY(_inst_name), \
527 .suite = #suite_name, \
528 }; \
529 \
530 DELETE_PAREN param_gen; \
531 \
532 list_add_tail(&_test_param_list, ¶m_node.node); \
533 }
534
has_disabled_prefix(const char * str)535 static inline bool has_disabled_prefix(const char* str) {
536 const char disabled_prefix[] = "DISABLED_";
537 return strncmp(str, disabled_prefix, strlen(disabled_prefix)) == 0;
538 }
539
trusty_unittest_test_is_disabled(struct test_list_node * entry)540 static inline bool trusty_unittest_test_is_disabled(
541 struct test_list_node* entry) {
542 return has_disabled_prefix(entry->suite) ||
543 has_disabled_prefix(entry->name);
544 }
545
546 /**
547 * trusty_unittest_count_param_entries - Count parameter entries for a given
548 * test suite.
549 *
550 * @suite: Name of test suite associated with the parameters
551 * suite is never going to be NULL (see invocation),
552 * no need to guard against this case.
553 *
554 * For each parameter generator associated with the suite, accrue
555 * the number of parameter entries.
556 *
557 * Not meant for external use.
558 *
559 * Return: count of parameter entries
560 */
trusty_unittest_count_param_entries(struct test_list_node * test_case)561 static int trusty_unittest_count_param_entries(
562 struct test_list_node* test_case) {
563 int param_count = 0;
564 int i;
565 struct test_param_list_node* param_entry;
566 bool has_param_gen = 0;
567 bool invalid_run = false;
568 /*
569 * for each parameter generator associated with the suite,
570 * accrue the number of parameter entries
571 */
572 list_for_every_entry(&_test_param_list, param_entry,
573 struct test_param_list_node, node) {
574 if (!strcmp(test_case->suite, param_entry->suite)) {
575 i = 0;
576 has_param_gen = true;
577 /* For each parameter from the generator */
578 while (param_entry->param_gen.gen_param(param_entry->param_gen.priv,
579 i)) {
580 i++;
581 }
582 if (!i) {
583 /*
584 * No parameter entries: parameterized test case exist
585 * but the test generator is empty
586 */
587 trusty_unittest_print_status_name_param_duration(
588 " FAILED ", param_entry->inst_name, test_case->suite,
589 test_case->name,
590 "NO PARAMS: Parameterized Test Case Generator without Params!",
591 "");
592 invalid_run = true;
593 }
594 param_count += i;
595 }
596 }
597 /*
598 * No parameter generator: parameterized test case exist
599 * but the test suite is not associated with any param generator
600 */
601 if (!has_param_gen) {
602 trusty_unittest_print_status_name_param_duration(
603 " FAILED ", "NO PARAM GENERATOR", test_case->suite,
604 test_case->name,
605 "NO PARAMS: Parameterized Test Case without Param Generator!",
606 "");
607 }
608 return invalid_run ? 0 : param_count;
609 }
610
611 /**
612 * trusty_unittest_has_parameterized_test_case - test suite with parameterized
613 * test cases
614 *
615 * @suite: Name of test suite associated with the parameters.
616 * suite is never going to be NULL (see invocation),
617 * no need to guard against this case.
618 *
619 * Check whether a test suite has parameterized test cases.
620 * Not meant for external use.
621 *
622 * Return: True if parameterized test
623 */
trusty_unittest_has_parameterized_test_case(const char * suite)624 static bool trusty_unittest_has_parameterized_test_case(const char* suite) {
625 struct test_list_node* test_case;
626 list_for_every_entry(&_test_list, test_case, struct test_list_node, node) {
627 if (!strcmp(suite, test_case->suite)) {
628 if (test_case->needs_param) {
629 return true;
630 }
631 }
632 }
633 return false;
634 }
635
636 /**
637 * trusty_unittest_count_test_cases - Count test cases associated with test
638 * suite.
639 *
640 * @suite: Name of test suite.
641 * When suite is NULL, all test cases from all test suites are counted.
642 *
643 * This test case count shall comply to the GTest parser requirements
644 * and thus shall not include disabled test cases.
645 * Not meant for external use.
646 *
647 * Return: count of test cases, -1 in case of detected test suite coding error
648 */
trusty_unittest_count_test_cases(const char * suite)649 static int trusty_unittest_count_test_cases(const char* suite) {
650 struct test_list_node* test_case;
651 struct test_param_list_node* param_entry;
652 bool test_code_error = false;
653 size_t test_case_count = 0;
654 bool disabled;
655 int param_entries = 0;
656 const char* param_entries_suite = NULL;
657 int current_test_case_count;
658 /* count all non parameterized and parameterized test cases */
659 list_for_every_entry(&_test_list, test_case, struct test_list_node, node) {
660 /* exclude tests not part of the requested suite */
661 if (suite && strcmp(suite, test_case->suite)) {
662 continue;
663 }
664 /* only count non-disabled test case as required by the GTest parser */
665 disabled = trusty_unittest_test_is_disabled(test_case);
666 if (test_case->needs_param) {
667 if (!param_entries_suite || !param_entries ||
668 strcmp(param_entries_suite, test_case->suite)) {
669 /* count param_entries for test_case->suite */
670 param_entries = trusty_unittest_count_param_entries(test_case);
671 param_entries_suite = test_case->suite;
672 }
673 if (!param_entries) {
674 /*
675 * Test code error shall be fixed and will prevent test
676 * execution however we don't bail right away with the goal of
677 * logging all erroneous test cases.
678 */
679 test_code_error = true;
680 continue;
681 }
682 current_test_case_count = param_entries;
683 } else {
684 current_test_case_count = 1;
685 }
686 if (!disabled) {
687 /* non parameterized (singular) test case */
688 test_case_count += current_test_case_count;
689 }
690 }
691 /*
692 * Search for a test coding issue where a test generator exists
693 * but is not backed by existing test case
694 */
695 list_for_every_entry(&_test_param_list, param_entry,
696 struct test_param_list_node, node) {
697 if (!trusty_unittest_has_parameterized_test_case(param_entry->suite)) {
698 test_code_error = true;
699 trusty_unittest_print_status_name_param_duration(
700 " FAILED ", param_entry->inst_name, param_entry->suite,
701 "NO_TESTS", "Parameter Generator without tests!", "");
702 }
703 }
704 return test_code_error ? -1 : test_case_count;
705 }
706
707 /**
708 * trusty_unittest_run_test_suite - run each test case associated with test
709 * suite.
710 *
711 * @suite: Name of test suite
712 * when suite is NULL, all test cases
713 * from all test suites are executed.
714 * @needs_param: when true run the parameterised test cases,
715 * otherwise run the non-parameterised test cases
716 *
717 * Not meant for external use.
718 *
719 * Return: count of executed test cases
720 */
trusty_unittest_run_test_suite(const char * suite,bool needs_param)721 static int trusty_unittest_run_test_suite(const char* suite, bool needs_param) {
722 struct test_list_node* entry;
723 int test_case_count = 0;
724
725 list_for_every_entry(&_test_list, entry, struct test_list_node, node) {
726 if ((!suite || !strcmp(suite, entry->suite)) &&
727 (entry->needs_param == needs_param)) {
728 if (trusty_unittest_test_is_disabled(entry)) {
729 trusty_unittest_print_status_name(entry->suite, entry->name,
730 "DISABLED");
731 _test_context.tests_disabled++;
732 } else {
733 test_case_count++;
734 entry->func();
735 }
736 }
737 }
738 return test_case_count;
739 }
740
741 /*
742 * The testing framework uses 3 global variables to keep track of tests and
743 * related data:
744 *
745 * _test_context: contains information about the overall execution of the
746 * framework (e.g. total tests run) and information about the currently
747 * executing test (e.g. test name, suite name).
748 *
749 * _test_list: contains a list of tests that can be run. Each test belongs to a
750 * test suite and may require parameters to be run.
751 *
752 * _test_param_list: contains a list of parameter generators for tests that
753 * require parameters. Each generator is associated with a specific test suite.
754 * Parameter generators are functions that return parameters that apply to all
755 * the tests that require parameters (i.e. parameterized tests) in a given test
756 * suite.
757 *
758 * Tests are only run as part of test suites. When a test suite is run all of
759 * the non-paremeterized tests belonging to that suite are run first followed by
760 * the parameterized tests in the suite. All of the parameterized tests in a
761 * suite are run once for each value returned by a parameter generator
762 * associated with that suite.
763 */
RUN_ALL_SUITE_TESTS(const char * suite)764 static inline bool RUN_ALL_SUITE_TESTS(const char* suite) {
765 struct test_param_list_node* param_entry;
766 const void* test_param;
767 int i;
768 char param_str[64];
769 int actual_test_count = 0;
770 int expected_test_count = trusty_unittest_count_test_cases(suite);
771 if (expected_test_count == -1) {
772 trusty_unittest_printf("Test Coding Error - aborting execution.\n");
773 return false;
774 }
775
776 trusty_unittest_printf(
777 "[==========] Running %d tests from %s test suite%s.\n",
778 expected_test_count, suite ? suite : "all", suite ? "" : "s");
779
780 _test_context.tests_total = 0;
781 _test_context.tests_disabled = 0;
782 _test_context.tests_failed = 0;
783 _test_context.test_param = NULL;
784 _test_context.inst_name = NULL;
785 _test_context.param_name = param_str;
786 _test_context.suite_duration_ms = 0;
787 /* Run all the non-parameterized tests in the suite */
788 actual_test_count = trusty_unittest_run_test_suite(suite, false);
789
790 /* For each parameter generator associated with the suite */
791 list_for_every_entry(&_test_param_list, param_entry,
792 struct test_param_list_node, node) {
793 if (!suite || !strcmp(suite, param_entry->suite)) {
794 i = 0;
795 /* For each parameter from the generator */
796 while ((test_param = param_entry->param_gen.gen_param(
797 param_entry->param_gen.priv, i))) {
798 /* Set the parameter for the next run */
799 _test_context.inst_name = param_entry->inst_name;
800 _test_context.test_param = test_param;
801 if (param_entry->to_string) {
802 param_entry->to_string(test_param, param_str,
803 sizeof(param_str));
804 } else {
805 snprintf(param_str, sizeof(param_str), "%d", i);
806 }
807 /* Run all the parameterized tests in the suite */
808 actual_test_count += trusty_unittest_run_test_suite(
809 param_entry->suite, true);
810 i++;
811 }
812 }
813 }
814 if (actual_test_count != expected_test_count) {
815 trusty_unittest_printf("[ RUN ] %s.test_count_match_check\n",
816 suite ? suite : "all_suites");
817 trusty_unittest_printf(
818 "[----------] %d tests ran, but expected %d tests.\n",
819 actual_test_count, expected_test_count);
820 trusty_unittest_print_status_name(suite ? suite : "all_suites",
821 "test_count_match_check", " FAILED ");
822 ++_test_context.tests_failed;
823 ++_test_context.tests_total;
824 } else if (actual_test_count == 0 && _test_context.tests_disabled == 0) {
825 trusty_unittest_printf("[ RUN ] %s.test_count_empty_check\n",
826 suite ? suite : "all_suites");
827 trusty_unittest_printf("[----------] 0 tests but none disabled.\n");
828 trusty_unittest_print_status_name(suite ? suite : "all_suites",
829 "test_count_empty_check", " FAILED ");
830 ++_test_context.tests_failed;
831 ++_test_context.tests_total;
832 }
833
834 trusty_unittest_printf(
835 "[==========] %d tests ran (%" PRIu64 " ms total).\n",
836 _test_context.tests_total, _test_context.suite_duration_ms);
837
838 if (_test_context.tests_total != _test_context.tests_failed) {
839 trusty_unittest_printf(
840 "[ PASSED ] %d tests.\n",
841 _test_context.tests_total - _test_context.tests_failed);
842 }
843 if (_test_context.tests_skipped) {
844 trusty_unittest_printf("[ SKIPPED ] %d tests.\n",
845 _test_context.tests_skipped);
846 }
847 if (_test_context.tests_disabled) {
848 trusty_unittest_printf("[ DISABLED ] %d tests.\n",
849 _test_context.tests_disabled);
850 }
851 if (_test_context.tests_failed) {
852 trusty_unittest_printf("[ FAILED ] %d tests.\n",
853 _test_context.tests_failed);
854 }
855 return _test_context.tests_failed == 0;
856 }
857
RUN_ALL_TESTS(void)858 static inline bool RUN_ALL_TESTS(void) {
859 return RUN_ALL_SUITE_TESTS(NULL);
860 }
861
862 /**
863 * GTEST_SKIP() - Skip current test
864 *
865 * This will skip the current test without triggering a failure. It will use
866 * same test_abort label as the ASSERT_... macros. Calling this after a test has
867 * failed or calling ASSERT_.../EXPECT_... macros after GTEST_SKIP has jumped
868 * to test_abort is not supported.
869 */
870 #define GTEST_SKIP() \
871 { \
872 if (!_test_context.skipped) { \
873 _test_context.skipped = true; \
874 _test_context.tests_skipped++; \
875 } \
876 goto test_abort; \
877 }
878
879 #define ASSERT_EXPECT_TEST(op, op_pre, op_sep, op_args, is_hard_fail, \
880 fail_action, vals_type, vals_format_placeholder, \
881 print_cast, print_op, val1, val2, extra_msg...) \
882 { \
883 vals_type _val1 = val1; \
884 vals_type _val2 = val2; \
885 if (!op_pre(_val1 DELETE_PAREN op_sep _val2 DELETE_PAREN op_args)) { \
886 trusty_unittest_printf("%s: @ %s:%d\n", _test_context.test_name, \
887 __FILE__, __LINE__); \
888 trusty_unittest_printf( \
889 " expected: %s (" vals_format_placeholder ") " print_op \
890 " %s (" vals_format_placeholder ")\n", \
891 #val1, print_cast _val1, #val2, print_cast _val2); \
892 trusty_unittest_printf(" " extra_msg); \
893 trusty_unittest_printf("\n"); \
894 if (_test_context.all_ok) { \
895 _test_context.all_ok = false; \
896 _test_context.tests_failed++; \
897 } \
898 _test_context.hard_fail |= is_hard_fail; \
899 fail_action \
900 } \
901 }
902
HasFailure(void)903 static inline bool HasFailure(void) {
904 return !_test_context.all_ok;
905 }
906
907 /**
908 * INSTANTIATE_TEST_SUITE_P - Instantiate parameters for a test suite
909 * @inst_name: Name for instantiation of parameters. Should not contain
910 * underscores.
911 * @suite_name: Name of test suite associated with the parameters
912 * @param_gen: One of the parameter generators (see below)
913 * @param_to_string: Function of type &typedef test_param_to_string_t
914 * used to convert a parameter to its string form. This
915 * argument is optional.
916 *
917 * Parameter Generators:
918 * testing_Range(being, end, step):
919 * Returns the values {begin, being+step, being+step+step, ...} up to but not
920 * including end. step is optional and defaults to 1.
921 *
922 * testing_Values(v1, v2, ..., vN):
923 * Returns the values {v1, v2, ..., vN)
924 *
925 * testing_ValuesIn(array)
926 * Returns the values in array
927 *
928 * testing_Bool()
929 * Returns {false, true}
930 *
931 * testing_Combine(g1, [g2, g3, g4, g5]):
932 * Returns the values of the combinations of the provided generators
933 * (min 1, max 5) an as an array.
934 */
935 #define INSTANTIATE_TEST_SUITE_P(inst_name, suite_name, param_gen_args...) \
936 INSTANTIATE_TEST_SUITE_P_INTERNAL(inst_name, suite_name, param_gen_args, \
937 NULL, )
938
939 /**
940 * GetParam() - Returns a pointer to the current test parameter
941 *
942 * Context: This function can be called within a parameterized test to
943 * retrieve the current parameter to the test.
944 *
945 * Return: a pointer to the current test parameter.
946 *
947 * This pointer should be cast to the expected parameter type for the executing
948 * test.
949 */
GetParam(void)950 static inline const void* GetParam(void) {
951 return _test_context.test_param;
952 }
953
954 #define ASSERT_EXPECT_LONG_TEST(op, is_hard_fail, fail_action, val1, val2, \
955 args...) \
956 ASSERT_EXPECT_TEST(op, , (op), (), is_hard_fail, fail_action, \
957 __typeof__(val2), "%ld", (long), #op, val1, val2, args)
958
959 #define ASSERT_EXPECT_STR_TEST(func, is_hard_fail, fail_action, args...) \
960 ASSERT_EXPECT_TEST(func, func, (, ), (), is_hard_fail, fail_action, \
961 const char*, "\"%s\"", , args)
962
963 #define ASSERT_EXPECT_STRN_TEST(func, n, is_hard_fail, fail_action, args...) \
964 ASSERT_EXPECT_TEST(func, func, (, ), (, n), is_hard_fail, fail_action, \
965 const char*, "\"%s\"", , args)
966
967 #define EXPECT_TEST(op, args...) ASSERT_EXPECT_LONG_TEST(op, false, , args)
968 #define EXPECT_EQ(args...) EXPECT_TEST(==, args)
969 #define EXPECT_NE(args...) EXPECT_TEST(!=, args)
970 #define EXPECT_LT(args...) EXPECT_TEST(<, args)
971 #define EXPECT_LE(args...) EXPECT_TEST(<=, args)
972 #define EXPECT_GT(args...) EXPECT_TEST(>, args)
973 #define EXPECT_GE(args...) EXPECT_TEST(>=, args)
974 #define EXPECT_STR_TEST(func, args...) \
975 ASSERT_EXPECT_STR_TEST(func, false, , args)
976 #define EXPECT_STREQ(args...) EXPECT_STR_TEST(!strcmp, "==", args)
977 #define EXPECT_STRNE(args...) EXPECT_STR_TEST(strcmp, "!=", args)
978 #define EXPECT_STRCASEEQ(args...) \
979 EXPECT_STR_TEST(!strcasecmp, "== (ignoring case)", args)
980 #define EXPECT_STRCASENE(args...) \
981 EXPECT_STR_TEST(strcasecmp, "!= (ignoring case)", args)
982 #define EXPECT_STRN_TEST(func, n, args...) \
983 ASSERT_EXPECT_STRN_TEST(func, n, false, , args)
984 #define EXPECT_STREQN(val1, val2, n, args...) \
985 EXPECT_STR_TEST(!strncmp, n, "==", val1, val2, args)
986 #define EXPECT_STRNEN(val1, val2, n, args...) \
987 EXPECT_STR_TEST(strncmp, n, "!=", val1, val2, args)
988 #define EXPECT_STRCASEEQN(val1, val2, n, args...) \
989 EXPECT_STR_TEST(!strncasecmp, n, "== (ignoring case)", val1, val2, args)
990 #define EXPECT_STRCASENEN(val1, val2, n, args...) \
991 EXPECT_STR_TEST(strncasecmp, n, "!= (ignoring case)", val1, val2, args)
992
993 #define ASSERT_TEST(op, args...) \
994 ASSERT_EXPECT_LONG_TEST(op, true, goto test_abort;, args)
995 #define ASSERT_EQ(args...) ASSERT_TEST(==, args)
996 #define ASSERT_NE(args...) ASSERT_TEST(!=, args)
997 #define ASSERT_LT(args...) ASSERT_TEST(<, args)
998 #define ASSERT_LE(args...) ASSERT_TEST(<=, args)
999 #define ASSERT_GT(args...) ASSERT_TEST(>, args)
1000 #define ASSERT_GE(args...) ASSERT_TEST(>=, args)
1001 #define ASSERT_STR_TEST(func, args...) \
1002 ASSERT_EXPECT_STR_TEST(func, true, goto test_abort;, args)
1003 #define ASSERT_STREQ(args...) ASSERT_STR_TEST(!strcmp, "==", args)
1004 #define ASSERT_STRNE(args...) ASSERT_STR_TEST(strcmp, "!=", args)
1005 #define ASSERT_STRCASEEQ(args...) \
1006 ASSERT_STR_TEST(!strcasecmp, "== (ignoring case)", args)
1007 #define ASSERT_STRCASENE(args...) \
1008 ASSERT_STR_TEST(strcasecmp, "!= (ignoring case)", args)
1009 #define ASSERT_STRN_TEST(func, n, args...) \
1010 ASSERT_EXPECT_STRN_TEST(func, n, true, goto test_abort;, args)
1011 #define ASSERT_STREQN(val1, val2, n, args...) \
1012 ASSERT_STRN_TEST(!strncmp, n, "==", val1, val2, args)
1013 #define ASSERT_STRNEN(val1, val2, n, args...) \
1014 ASSERT_STRN_TEST(strncmp, n, "!=", val1, val2, args)
1015 #define ASSERT_STRCASEEQN(val1, val2, n, args...) \
1016 ASSERT_STRN_TEST(!strncasecmp, n, "== (ignoring case)", val1, val2, args)
1017 #define ASSERT_STRCASENEN(val1, val2, n, args...) \
1018 ASSERT_STRN_TEST(strncasecmp, n, "!= (ignoring case)", val1, val2, args)
1019
1020 __END_CDECLS
1021