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, &param_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