1 /* 2 * Copyright(c) 2023 Legrand North America, LLC. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @file 9 * 10 * @brief Zephyr testing framework FFF extension macros 11 */ 12 13 #ifndef ZEPHYR_SUBSYS_TESTSUITE_INCLUDE_ZEPHYR_FFF_EXTENSIONS_H_ 14 #define ZEPHYR_SUBSYS_TESTSUITE_INCLUDE_ZEPHYR_FFF_EXTENSIONS_H_ 15 16 #include <zephyr/fff.h> 17 #include <zephyr/sys/util.h> /* for CONTAINER_OF */ 18 19 /** 20 * @defgroup fff_extensions FFF extensions 21 * @ingroup testing 22 * 23 * This module provides extensions to FFF for simplifying the 24 * configuration and usage of fakes. 25 * 26 * @{ 27 */ 28 29 30 /** 31 * @brief Wrap custom fake body to extract defined context struct 32 * 33 * Add extension macro for simplified creation of 34 * fake functions needing call-specific context data. 35 * 36 * This macro enables a fake to be implemented as follows and 37 * requires no familiarity with the inner workings of FFF. 38 * 39 * @code 40 * struct FUNCNAME##_custom_fake_context 41 * { 42 * struct instance * const instance; 43 * int result; 44 * }; 45 * 46 * int FUNCNAME##_custom_fake( 47 * const struct instance **instance_out) 48 * { 49 * RETURN_HANDLED_CONTEXT( 50 * FUNCNAME, 51 * struct FUNCNAME##_custom_fake_context, 52 * result, 53 * context, 54 * { 55 * if (context != NULL) 56 * { 57 * if (context->result == 0) 58 * { 59 * if (instance_out != NULL) 60 * { 61 * *instance_out = context->instance; 62 * } 63 * } 64 * return context->result; 65 * } 66 * return FUNCNAME##_fake.return_val; 67 * } 68 * ); 69 * } 70 * @endcode 71 * 72 * @param FUNCNAME Name of function being faked 73 * @param CONTEXTTYPE type of custom defined fake context struct 74 * @param RESULTFIELD name of field holding the return type & value 75 * @param CONTEXTPTRNAME expected name of pointer to custom defined fake context struct 76 * @param HANDLERBODY in-line custom fake handling logic 77 */ 78 79 #define RETURN_HANDLED_CONTEXT(FUNCNAME, \ 80 CONTEXTTYPE, RESULTFIELD, CONTEXTPTRNAME, HANDLERBODY) \ 81 if (FUNCNAME##_fake.return_val_seq_len) { \ 82 CONTEXTTYPE * const contexts = \ 83 CONTAINER_OF(FUNCNAME##_fake.return_val_seq, \ 84 CONTEXTTYPE, RESULTFIELD); \ 85 size_t const seq_idx = (FUNCNAME##_fake.return_val_seq_idx < \ 86 FUNCNAME##_fake.return_val_seq_len) ? \ 87 FUNCNAME##_fake.return_val_seq_idx++ :\ 88 FUNCNAME##_fake.return_val_seq_idx - 1;\ 89 CONTEXTTYPE * const CONTEXTPTRNAME = &contexts[seq_idx]; \ 90 HANDLERBODY; \ 91 } \ 92 return FUNCNAME##_fake.return_val 93 94 /** 95 * @} 96 */ 97 98 #endif /* ZEPHYR_SUBSYS_TESTSUITE_INCLUDE_ZEPHYR_FFF_EXTENSIONS_H_ */ 99