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 <lk/compiler.h>
27 #include <lk/list.h>
28 #include <stdbool.h>
29 #include <string.h>
30
31 __BEGIN_CDECLS
32
33 /*
34 * Test functions can be defined with:
35 * TEST(SuiteName, TestName) {
36 * ... test body ...
37 * }
38 * or with:
39 * TEST_F(SuiteName, TestName) {
40 * ... test body ...
41 * }
42 * or with:
43 * TEST_P(SuiteName, TestName) {
44 * ... test body ...
45 * }
46 *
47 * NOTE: SuiteName and TestName should not contain underscores.
48 *
49 * Use EXPECT_<op> or ASSERT_<op> directly in test functions or from nested
50 * functions to check test conditions. Where <op> can be:
51 * EQ for ==
52 * NE for !=
53 * LT for <
54 * LE for <=
55 * GT for >
56 * GE for >=
57 *
58 * The test functions follows this pattern:
59 * <EXPECT|ASSERT>_<op>(val1, val2 [, format, ...])
60 * If val1 <op> val2 is not true, then both values will be printed and a test
61 * failure will be recorded. For ASSERT_<op> it will also jump to a test_abort
62 * label in the calling function.
63 *
64 * Call RUN_ALL_TESTS() to run all tests defined by TEST (or
65 * RUN_ALL_SUITE_TESTS("SuiteName") to only run tests with the specified
66 * SuiteName). RUN_ALL_TESTS and RUN_ALL_SUITE_TESTS return true if all the
67 * tests passed.
68 *
69 * Test functions defined with TEST_F or TEST_P expect the type <SuiteName>_t
70 * and <SuiteName>_SetUp and <SuiteName>_TearDown functions to be defined.
71 * The <SuiteName>_SetUp function will be called once before each test in
72 * SuiteName in run and the <SuiteName>_TearDown function will be called once
73 * after each test in SuiteName is run. These functions can be defined with
74 * TEST_F_SETUP(<SuiteName>) {
75 * ... setup body ...
76 * }
77 * and with:
78 * TEST_F_TEARDOWN(<SuiteName>) {
79 * ... teardown body ...
80 * }
81 * A pointer to a <SuiteName>_t variable will be passed as "_state" to the
82 * setup, teardown and test functions.
83 *
84 * TEST_FIXTURE_ALIAS(NewSuiteName, OldSuiteName) can be used to use the test
85 * fixture defined for OldSuiteName with NewSuiteName.
86 *
87 * Tests defined with TEST_P will only run when their suite is run if they have
88 * been instantiated with parameters using INSTANTIATE_TEST_SUITE_P. These tests
89 * can access their parameter using GetParam()
90 */
91
92 #ifndef trusty_unittest_printf
93 #error trusty_unittest_printf must be defined
94 #endif
95
96 /**
97 * struct test_context - struct representing the state of a test run.
98 * @tests_total: Number of conditions checked
99 * @tests_skipped: Number of tests skipped
100 * @tests_disabled: Number of disabled tests skipped
101 * @tests_failed: Number of conditions failed
102 * @inst_name: Name of the current parameter instantiation
103 * @suite_name: Name of the current test suite
104 * @param_name: Name of the current parameter
105 * @test_name: Name of current test case
106 * @test_param: The current test parameter
107 * @all_ok: State of current test case
108 * @skipped: Current test was skipped.
109 * @hard_fail: Type of test failure (when @all_ok is false)
110 */
111 struct test_context {
112 unsigned int tests_total;
113 unsigned int tests_skipped;
114 unsigned int tests_disabled;
115 unsigned int tests_failed;
116 const char* inst_name;
117 const char* suite_name;
118 const char* param_name;
119 const char* test_name;
120 const void* test_param;
121 bool all_ok;
122 bool skipped;
123 bool hard_fail;
124 };
125
126 /**
127 * struct test_list_node - node to hold test function in list of tests
128 * @node: List node
129 * @suite: Name of test suite (optionally used for filtering)
130 * @name: Name of test (optionally used for filtering)
131 * @func: Test function
132 * @needs_param: Indicates if the test function is parameterized
133 */
134
135 struct test_list_node {
136 struct list_node node;
137 const char* suite;
138 const char* name;
139 void (*func)(void);
140 bool needs_param;
141 };
142
143 /**
144 * struct test_param_gen - struct representing a parameter generator
145 * @gen_param: Function to generate the parameter for a test
146 * @priv: Private data passed to gen_param
147 */
148 struct test_param_gen {
149 const void* (*gen_param)(void*, int);
150 void* priv;
151 };
152
153 /**
154 * typedef test_param_to_string_t - Converts a test parameter to its string form
155 * @param: Parameter to convert
156 * @buf: Buffer to fill with a NULL terminated string representation of
157 * @param
158 * @buf_size: Size in bytes of @buf
159 *
160 * When called, this function is passed a pointer to the parameter for the test
161 * that is being executed in @param and must return a null-terminated string
162 * representing the passed in parameter in @buf of at most size @buf_size.
163 */
164 typedef void (*test_param_to_string_t)(const void* param,
165 char* buf,
166 size_t buf_size);
167
168 /**
169 * struct test_param_list_node - holds parameter generators
170 * @node: List node
171 * @param_gen: Parameter generator
172 * @to_string: Function to convert a parameter to its string form
173 * @inst_name: Name of the instantiation associated with the generator
174 * @suite: Name of test suite associated with the generator
175 */
176
177 struct test_param_list_node {
178 struct list_node node;
179 struct test_param_gen param_gen;
180 test_param_to_string_t to_string;
181 const char* inst_name;
182 const char* suite;
183 };
184
185 static struct test_context _test_context;
186
187 /*
188 * List of tests. Tests are added by a __attribute__((constructor)) function
189 * per test defined by the TEST macro.
190 */
191 static struct list_node _test_list = LIST_INITIAL_VALUE(_test_list);
192
193 /*
194 * List of parameter generators. Parameter generators are added by a
195 * __attribute__((constructor)) function per instantiation defined with
196 * INSTANTIATE_TEST_SUITE_P.
197 */
198 static struct list_node _test_param_list = LIST_INITIAL_VALUE(_test_param_list);
199
trusty_unittest_print_status_name(const char * suite_name,const char * test_name,const char * status)200 static inline void trusty_unittest_print_status_name(const char* suite_name,
201 const char* test_name,
202 const char* status) {
203 if (_test_context.test_param) {
204 trusty_unittest_printf("[ %s ] %s/%s.%s/%s\n", status,
205 _test_context.inst_name, suite_name, test_name,
206 _test_context.param_name);
207 } else {
208 trusty_unittest_printf("[ %s ] %s.%s\n", status, suite_name, test_name);
209 }
210 }
211
trusty_unittest_print_status(const char * status)212 static inline void trusty_unittest_print_status(const char* status) {
213 trusty_unittest_print_status_name(_test_context.suite_name,
214 _test_context.test_name, status);
215 }
216
TEST_BEGIN_FUNC(const char * suite_name,const char * test_name)217 static inline void TEST_BEGIN_FUNC(const char* suite_name,
218 const char* test_name) {
219 _test_context.suite_name = suite_name;
220 _test_context.test_name = test_name;
221 _test_context.all_ok = true;
222 _test_context.hard_fail = false;
223 _test_context.skipped = false;
224 _test_context.tests_total++;
225 trusty_unittest_print_status("RUN ");
226 }
227
TEST_END_FUNC(void)228 static inline void TEST_END_FUNC(void) {
229 if (_test_context.skipped) {
230 trusty_unittest_print_status(" SKIPPED");
231 } else if (_test_context.all_ok) {
232 trusty_unittest_print_status(" OK");
233 } else {
234 trusty_unittest_print_status(" FAILED ");
235 }
236 _test_context.test_name = NULL;
237 }
238
239 #define STRINGIFY(x) #x
240
241 #define TEST_FIXTURE_ALIAS(new_suite_name, old_suite_name) \
242 typedef old_suite_name##_t new_suite_name##_t; \
243 \
244 static void new_suite_name##_SetUp(new_suite_name##_t* _state) { \
245 old_suite_name##_SetUp(_state); \
246 } \
247 static void new_suite_name##_TearDown(new_suite_name##_t* _state) { \
248 old_suite_name##_TearDown(_state); \
249 }
250
251 #define TEST_INTERNAL(suite_name, test_name, w_param, pre, post, arg, argp) \
252 static void suite_name##_##test_name##_inner argp; \
253 \
254 static void suite_name##_##test_name(void) { \
255 TEST_BEGIN_FUNC(STRINGIFY(suite_name), STRINGIFY(test_name)); \
256 { \
257 pre; \
258 if (!_test_context.hard_fail && !_test_context.skipped) { \
259 suite_name##_##test_name##_inner arg; \
260 } \
261 post; \
262 } \
263 TEST_END_FUNC(); \
264 } \
265 \
266 static struct test_list_node suite_name##_##test_name##_node = { \
267 .node = LIST_INITIAL_CLEARED_VALUE, \
268 .suite = #suite_name, \
269 .name = #test_name, \
270 .func = suite_name##_##test_name, \
271 .needs_param = w_param, \
272 }; \
273 \
274 __attribute__((constructor)) void suite_name##_##test_name##_add(void) { \
275 list_add_tail(&_test_list, &suite_name##_##test_name##_node.node); \
276 } \
277 \
278 static void suite_name##_##test_name##_inner argp
279
280 #define TEST_F_SETUP(suite_name) \
281 static void suite_name##_SetUp(suite_name##_t* _state)
282
283 #define TEST_F_TEARDOWN(suite_name) \
284 static void suite_name##_TearDown(suite_name##_t* _state)
285
286 #define TEST(suite_name, test_name) \
287 TEST_INTERNAL(suite_name, test_name, false, , , (), (void))
288
289 #define TEST_F_CUSTOM_ARGS(suite_name, test_name, arg, argp) \
290 TEST_INTERNAL(suite_name, test_name, false, suite_name##_t state; \
291 suite_name##_SetUp(&state);, suite_name##_TearDown(&state); \
292 , arg, argp)
293
294 #define TEST_F(suite_name, test_name) \
295 TEST_F_CUSTOM_ARGS(suite_name, test_name, (&state), \
296 (suite_name##_t * _state))
297
298 #define TEST_P_CUSTOM_ARGS(suite_name, test_name, arg, argp) \
299 TEST_INTERNAL(suite_name, test_name, true, suite_name##_t state; \
300 suite_name##_SetUp(&state);, suite_name##_TearDown(&state); \
301 , arg, argp)
302
303 #define TEST_P(suite_name, test_name) \
304 TEST_P_CUSTOM_ARGS(suite_name, test_name, (&state), \
305 (suite_name##_t * _state))
306
307 struct test_array_param {
308 const void* arr;
309 int elem_size;
310 int count;
311 };
312
test_gen_array_param(void * priv,int i)313 static inline const void* test_gen_array_param(void* priv, int i) {
314 struct test_array_param* param = (struct test_array_param*)priv;
315
316 if (i >= param->count) {
317 return NULL;
318 }
319
320 return (uint8_t*)param->arr + param->elem_size * i;
321 }
322
323 struct test_range_param {
324 long begin;
325 long end;
326 long step;
327 long current;
328 };
329
test_gen_range_param(void * priv,int i)330 static inline const void* test_gen_range_param(void* priv, int i) {
331 struct test_range_param* range_param = (struct test_range_param*)priv;
332
333 range_param->current = range_param->begin + range_param->step * i;
334
335 if (range_param->current >= range_param->end) {
336 return NULL;
337 }
338
339 return &range_param->current;
340 }
341
342 struct combined_params {
343 struct test_param_gen* generators;
344 int generator_count;
345 int* idxs;
346 const void** current;
347 };
348
update_combined_params(struct combined_params * params,int j,bool reset)349 static inline void update_combined_params(struct combined_params* params,
350 int j,
351 bool reset) {
352 if (reset) {
353 params->idxs[j] = 0;
354 }
355
356 params->current[j] = params->generators[j].gen_param(
357 params->generators[j].priv, params->idxs[j]);
358 params->idxs[j]++;
359 }
360
test_gen_combined_param(void * priv,int i)361 static inline const void* test_gen_combined_param(void* priv, int i) {
362 struct combined_params* params = (struct combined_params*)priv;
363
364 if (i == 0) {
365 for (int j = 0; j < params->generator_count; j++) {
366 update_combined_params(params, j, true);
367 }
368 return params->current;
369 }
370
371 for (int j = 0; j < params->generator_count; j++) {
372 update_combined_params(params, j, false);
373
374 if (params->current[j] != NULL) {
375 return params->current;
376 }
377
378 update_combined_params(params, j, true);
379 }
380
381 return NULL;
382 }
383
384 #define FIRST_ARG(arg0, args...) arg0
385 #define SECOND_ARG(arg0, arg1, args...) arg1
386 /* Parentheses are used to prevent commas from being interpreted when they are
387 * passed in macro arguments. DELETE_PAREN is used to remove these parentheses
388 * inside the macro that uses the commas e.g.:
389 *
390 * MY_MACRO((1, 2, 3))
391 *
392 * #define MY_MACRO(arg)
393 * DELETE_PAREN arg
394 */
395 #define DELETE_PAREN(args...) args
396
397 #define testing_Range(_begin, end_step...) \
398 (static struct test_range_param range_param = \
399 { \
400 .begin = _begin, \
401 .end = FIRST_ARG(end_step, ), \
402 .step = SECOND_ARG(end_step, 1, ), \
403 }; \
404 param_node.param_gen.gen_param = test_gen_range_param; \
405 param_node.param_gen.priv = &range_param;)
406
407 #define testing_ValuesIn(array) \
408 (static struct test_array_param array_param = \
409 { \
410 .arr = array, \
411 .elem_size = sizeof(array[0]), \
412 .count = countof(array), \
413 }; \
414 \
415 param_node.param_gen.gen_param = test_gen_array_param; \
416 param_node.param_gen.priv = &array_param;)
417
418 /*
419 * (args, args) is passed to __typeof__ to guarantee that it resolves to const
420 * char* instead of const char[] in cases where args contains a single string.
421 * When args is a single string, it is inlined and typeof will resolve to const
422 * char[].
423 */
424 #define testing_Values(args...) \
425 (static __typeof__(args, args) new_arr[] = {args}; \
426 DELETE_PAREN testing_ValuesIn(new_arr))
427
428 #define testing_Bool() testing_Values(false, true)
429
430 #define test_set_combine_params(generator, i, count) \
431 { \
432 DELETE_PAREN generator; \
433 if (i < count) { \
434 param_gens[i].gen_param = param_node.param_gen.gen_param; \
435 param_gens[i].priv = param_node.param_gen.priv; \
436 } \
437 }
438
439 #define testing_Combine_internal(arg0, arg1, arg2, arg3, arg4, arg5, arg6, \
440 arg7, arg8, arg9, da0, da1, da2, da3, da4, \
441 da5, da6, da7, da8, da9, count, args...) \
442 (static struct test_param_gen param_gens[count]; static int idxs[count]; \
443 static const void* current_params[count]; \
444 static struct combined_params combined_params = \
445 { \
446 param_gens, \
447 count, \
448 idxs, \
449 current_params, \
450 }; \
451 \
452 test_set_combine_params(arg0, 0, count); \
453 test_set_combine_params(arg1, 1, count); \
454 test_set_combine_params(arg2, 2, count); \
455 test_set_combine_params(arg3, 3, count); \
456 test_set_combine_params(arg4, 4, count); \
457 test_set_combine_params(arg5, 5, count); \
458 test_set_combine_params(arg6, 6, count); \
459 test_set_combine_params(arg7, 7, count); \
460 test_set_combine_params(arg8, 8, count); \
461 test_set_combine_params(arg9, 9, count); \
462 param_node.param_gen.gen_param = test_gen_combined_param; \
463 param_node.param_gen.priv = &combined_params;)
464
465 #define testing_Combine(generators...) \
466 testing_Combine_internal(generators, (), (), (), (), (), (), (), (), (), \
467 (), 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
468
469 #define INSTANTIATE_TEST_SUITE_P_INTERNAL(_inst_name, suite_name, param_gen, \
470 param_to_string, args...) \
471 \
472 __attribute__((constructor)) void suite_name##_##_inst_name##param_add( \
473 void) { \
474 static struct test_param_list_node param_node = { \
475 .node = LIST_INITIAL_CLEARED_VALUE, \
476 .to_string = param_to_string, \
477 .inst_name = STRINGIFY(_inst_name), \
478 .suite = #suite_name, \
479 }; \
480 \
481 DELETE_PAREN param_gen; \
482 \
483 list_add_tail(&_test_param_list, ¶m_node.node); \
484 }
485
has_disabled_prefix(const char * str)486 static inline bool has_disabled_prefix(const char* str) {
487 const char disabled_prefix[] = "DISABLED_";
488 return strncmp(str, disabled_prefix, strlen(disabled_prefix)) == 0;
489 }
490
test_is_disabled(struct test_list_node * entry)491 static inline bool test_is_disabled(struct test_list_node* entry) {
492 return has_disabled_prefix(entry->suite) ||
493 has_disabled_prefix(entry->name);
494 }
495
test_suite_instantiated(const char * suite)496 static bool test_suite_instantiated(const char* suite) {
497 struct test_param_list_node* param_entry;
498 list_for_every_entry(&_test_param_list, param_entry,
499 struct test_param_list_node, node) {
500 if (!strcmp(suite, param_entry->suite)) {
501 return true;
502 }
503 }
504 return false;
505 }
506
run_test_suite(const char * suite,bool needs_param)507 static void run_test_suite(const char* suite, bool needs_param) {
508 struct test_list_node* entry;
509 bool valid_suite = false;
510
511 list_for_every_entry(&_test_list, entry, struct test_list_node, node) {
512 if ((!suite || !strcmp(suite, entry->suite)) &&
513 (entry->needs_param == needs_param)) {
514 valid_suite = true;
515 if (test_is_disabled(entry)) {
516 trusty_unittest_print_status_name(entry->suite, entry->name,
517 "DISABLED");
518 _test_context.tests_disabled++;
519 } else {
520 entry->func();
521 }
522 }
523 if (!needs_param && entry->needs_param &&
524 !test_suite_instantiated(entry->suite)) {
525 trusty_unittest_print_status_name(entry->suite, entry->name,
526 "NO PARAM");
527 _test_context.tests_failed++;
528 }
529 }
530 if (needs_param && !valid_suite) {
531 trusty_unittest_print_status_name(suite, "[NO TESTS]", " FAILED ");
532 _test_context.tests_failed++;
533 }
534 }
535
536 /*
537 * The testing framework uses 3 global variables to keep track of tests and
538 * related data:
539 *
540 * _test_context: contains information about the overall execution of the
541 * framework (e.g. total tests run) and information about the currently
542 * executing test (e.g. test name, suite name).
543 *
544 * _test_list: contains a list of tests that can be run. Each test belongs to a
545 * test suite and may require parameters to be run.
546 *
547 * _test_param_list: contains a list of parameter generators for tests that
548 * require parameters. Each generator is associated with a specific test suite.
549 * Parameter generators are functions that return parameters that apply to all
550 * the tests that require parameters (i.e. parameterized tests) in a given test
551 * suite.
552 *
553 * Tests are only run as part of test suites. When a test suite is run all of
554 * the non-paremeterized tests belonging to that suite are run first followed by
555 * the parameterized tests in the suite. All of the parameterized tests in a
556 * suite are run once for each value returned by a parameter generator
557 * associated with that suite.
558 */
RUN_ALL_SUITE_TESTS(const char * suite)559 static inline bool RUN_ALL_SUITE_TESTS(const char* suite) {
560 struct test_param_list_node* param_entry;
561 const void* test_param;
562 int i;
563 char param_str[64];
564 _test_context.tests_total = 0;
565 _test_context.tests_disabled = 0;
566 _test_context.tests_failed = 0;
567 _test_context.test_param = NULL;
568 _test_context.param_name = param_str;
569
570 /* Run all the non-parameterized tests in the suite */
571 run_test_suite(suite, false);
572
573 /* For each parameter generator associated with the suite */
574 list_for_every_entry(&_test_param_list, param_entry,
575 struct test_param_list_node, node) {
576 if (!suite || !strcmp(suite, param_entry->suite)) {
577 i = 0;
578 /* For each parameter from the generator */
579 while ((test_param = param_entry->param_gen.gen_param(
580 param_entry->param_gen.priv, i))) {
581 /* Set the parameter for the next run */
582 _test_context.inst_name = param_entry->inst_name;
583 _test_context.test_param = test_param;
584 if (param_entry->to_string) {
585 param_entry->to_string(test_param, param_str,
586 sizeof(param_str));
587 } else {
588 snprintf(param_str, sizeof(param_str), "%d", i);
589 }
590 /* Run all the parameterized tests in the suite */
591 run_test_suite(param_entry->suite, true);
592 i++;
593 }
594 }
595 }
596
597 trusty_unittest_printf("[==========] %d tests ran.\n",
598 _test_context.tests_total);
599 if (_test_context.tests_total != _test_context.tests_failed) {
600 trusty_unittest_printf(
601 "[ PASSED ] %d tests.\n",
602 _test_context.tests_total - _test_context.tests_failed);
603 }
604 if (_test_context.tests_skipped) {
605 trusty_unittest_printf("[ SKIPPED ] %d tests.\n",
606 _test_context.tests_skipped);
607 }
608 if (_test_context.tests_disabled) {
609 trusty_unittest_printf("[ DISABLED ] %d tests.\n",
610 _test_context.tests_disabled);
611 }
612 if (_test_context.tests_failed) {
613 trusty_unittest_printf("[ FAILED ] %d tests.\n",
614 _test_context.tests_failed);
615 }
616 return _test_context.tests_failed == 0;
617 }
618
RUN_ALL_TESTS(void)619 static inline bool RUN_ALL_TESTS(void) {
620 return RUN_ALL_SUITE_TESTS(NULL);
621 }
622
623 /**
624 * GTEST_SKIP() - Skip current test
625 *
626 * This will skip the current test without triggering a failure. It will use
627 * same test_abort label as the ASSERT_... macros. Calling this after a test has
628 * failed or calling ASSERT_.../EXPECT_... macros after GTEST_SKIP has jumped
629 * to test_abort is not supported.
630 */
631 #define GTEST_SKIP() \
632 { \
633 if (!_test_context.skipped) { \
634 _test_context.skipped = true; \
635 _test_context.tests_skipped++; \
636 } \
637 goto test_abort; \
638 }
639
640 #define ASSERT_EXPECT_TEST(op, op_pre, op_sep, op_args, is_hard_fail, \
641 fail_action, vals_type, vals_format_placeholder, \
642 print_cast, print_op, val1, val2, extra_msg...) \
643 { \
644 vals_type _val1 = val1; \
645 vals_type _val2 = val2; \
646 if (!op_pre(_val1 DELETE_PAREN op_sep _val2 DELETE_PAREN op_args)) { \
647 trusty_unittest_printf("%s: @ %s:%d\n", _test_context.test_name, \
648 __FILE__, __LINE__); \
649 trusty_unittest_printf( \
650 " expected: %s (" vals_format_placeholder ") " print_op \
651 " %s (" vals_format_placeholder ")\n", \
652 #val1, print_cast _val1, #val2, print_cast _val2); \
653 trusty_unittest_printf(" " extra_msg); \
654 trusty_unittest_printf("\n"); \
655 if (_test_context.all_ok) { \
656 _test_context.all_ok = false; \
657 _test_context.tests_failed++; \
658 } \
659 _test_context.hard_fail |= is_hard_fail; \
660 fail_action \
661 } \
662 }
663
HasFailure(void)664 static inline bool HasFailure(void) {
665 return !_test_context.all_ok;
666 }
667
668 /**
669 * INSTANTIATE_TEST_SUITE_P - Instantiate parameters for a test suite
670 * @inst_name: Name for instantiation of parameters. Should not contain
671 * underscores.
672 * @suite_name: Name of test suite associated with the parameters
673 * @param_gen: One of the parameter generators (see below)
674 * @param_to_string: Function of type &typedef test_param_to_string_t
675 * used to convert a parameter to its string form. This
676 * argument is optional.
677 *
678 * Parameter Generators:
679 * testing_Range(being, end, step):
680 * Returns the values {begin, being+step, being+step+step, ...} up to but not
681 * including end. step is optional and defaults to 1.
682 *
683 * testing_Values(v1, v2, ..., vN):
684 * Returns the values {v1, v2, ..., vN)
685 *
686 * testing_ValuesIn(array)
687 * Returns the values in array
688 *
689 * testing_Bool()
690 * Returns {false, true}
691 *
692 * testing_Combine(g1, [g2, g3, g4, g5]):
693 * Returns the values of the combinations of the provided generators
694 * (min 1, max 5) an as an array.
695 */
696 #define INSTANTIATE_TEST_SUITE_P(inst_name, suite_name, param_gen_args...) \
697 INSTANTIATE_TEST_SUITE_P_INTERNAL(inst_name, suite_name, param_gen_args, \
698 NULL, )
699
700 /**
701 * GetParam() - Returns a pointer to the current test parameter
702 *
703 * Context: This function can be called within a parameterized test to
704 * retrieve the current parameter to the test.
705 *
706 * Return: a pointer to the current test parameter.
707 *
708 * This pointer should be cast to the expected parameter type for the executing
709 * test.
710 */
GetParam(void)711 static inline const void* GetParam(void) {
712 return _test_context.test_param;
713 }
714
715 #define ASSERT_EXPECT_LONG_TEST(op, is_hard_fail, fail_action, val1, val2, \
716 args...) \
717 ASSERT_EXPECT_TEST(op, , (op), (), is_hard_fail, fail_action, \
718 __typeof__(val2), "%ld", (long), #op, val1, val2, args)
719
720 #define ASSERT_EXPECT_STR_TEST(func, is_hard_fail, fail_action, args...) \
721 ASSERT_EXPECT_TEST(func, func, (, ), (), is_hard_fail, fail_action, \
722 const char*, "\"%s\"", , args)
723
724 #define ASSERT_EXPECT_STRN_TEST(func, n, is_hard_fail, fail_action, args...) \
725 ASSERT_EXPECT_TEST(func, func, (, ), (, n), is_hard_fail, fail_action, \
726 const char*, "\"%s\"", , args)
727
728 #define EXPECT_TEST(op, args...) ASSERT_EXPECT_LONG_TEST(op, false, , args)
729 #define EXPECT_EQ(args...) EXPECT_TEST(==, args)
730 #define EXPECT_NE(args...) EXPECT_TEST(!=, args)
731 #define EXPECT_LT(args...) EXPECT_TEST(<, args)
732 #define EXPECT_LE(args...) EXPECT_TEST(<=, args)
733 #define EXPECT_GT(args...) EXPECT_TEST(>, args)
734 #define EXPECT_GE(args...) EXPECT_TEST(>=, args)
735 #define EXPECT_STR_TEST(func, args...) \
736 ASSERT_EXPECT_STR_TEST(func, false, , args)
737 #define EXPECT_STREQ(args...) EXPECT_STR_TEST(!strcmp, "==", args)
738 #define EXPECT_STRNE(args...) EXPECT_STR_TEST(strcmp, "!=", args)
739 #define EXPECT_STRCASEEQ(args...) \
740 EXPECT_STR_TEST(!strcasecmp, "== (ignoring case)", args)
741 #define EXPECT_STRCASENE(args...) \
742 EXPECT_STR_TEST(strcasecmp, "!= (ignoring case)", args)
743 #define EXPECT_STRN_TEST(func, n, args...) \
744 ASSERT_EXPECT_STRN_TEST(func, n, false, , args)
745 #define EXPECT_STREQN(val1, val2, n, args...) \
746 EXPECT_STR_TEST(!strncmp, n, "==", val1, val2, args)
747 #define EXPECT_STRNEN(val1, val2, n, args...) \
748 EXPECT_STR_TEST(strncmp, n, "!=", val1, val2, args)
749 #define EXPECT_STRCASEEQN(val1, val2, n, args...) \
750 EXPECT_STR_TEST(!strncasecmp, n, "== (ignoring case)", val1, val2, args)
751 #define EXPECT_STRCASENEN(val1, val2, n, args...) \
752 EXPECT_STR_TEST(strncasecmp, n, "!= (ignoring case)", val1, val2, args)
753
754 #define ASSERT_TEST(op, args...) \
755 ASSERT_EXPECT_LONG_TEST(op, true, goto test_abort;, args)
756 #define ASSERT_EQ(args...) ASSERT_TEST(==, args)
757 #define ASSERT_NE(args...) ASSERT_TEST(!=, args)
758 #define ASSERT_LT(args...) ASSERT_TEST(<, args)
759 #define ASSERT_LE(args...) ASSERT_TEST(<=, args)
760 #define ASSERT_GT(args...) ASSERT_TEST(>, args)
761 #define ASSERT_GE(args...) ASSERT_TEST(>=, args)
762 #define ASSERT_STR_TEST(func, args...) \
763 ASSERT_EXPECT_STR_TEST(func, true, goto test_abort;, args)
764 #define ASSERT_STREQ(args...) ASSERT_STR_TEST(!strcmp, "==", args)
765 #define ASSERT_STRNE(args...) ASSERT_STR_TEST(strcmp, "!=", args)
766 #define ASSERT_STRCASEEQ(args...) \
767 ASSERT_STR_TEST(!strcasecmp, "== (ignoring case)", args)
768 #define ASSERT_STRCASENE(args...) \
769 ASSERT_STR_TEST(strcasecmp, "!= (ignoring case)", args)
770 #define ASSERT_STRN_TEST(func, n, args...) \
771 ASSERT_EXPECT_STRN_TEST(func, n, true, goto test_abort;, args)
772 #define ASSERT_STREQN(val1, val2, n, args...) \
773 ASSERT_STRN_TEST(!strncmp, n, "==", val1, val2, args)
774 #define ASSERT_STRNEN(val1, val2, n, args...) \
775 ASSERT_STRN_TEST(strncmp, n, "!=", val1, val2, args)
776 #define ASSERT_STRCASEEQN(val1, val2, n, args...) \
777 ASSERT_STRN_TEST(!strncasecmp, n, "== (ignoring case)", val1, val2, args)
778 #define ASSERT_STRCASENEN(val1, val2, n, args...) \
779 ASSERT_STRN_TEST(strncasecmp, n, "!= (ignoring case)", val1, val2, args)
780
781 __END_CDECLS
782