testing/mock.h (365 lines of code) (raw):

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. #ifndef MOCK_H_ #define MOCK_H_ #include <stdbool.h> #include <stddef.h> #include <stdint.h> #include "common/array_size.h" #include "status/rot_status.h" struct mock_arg; /** * Signature for a custom validation routine to execute more complicated argument validation. * * No error output for argument validation will be generated by standard mock validation flows when * using custom validation. It is required that validation error messages be generated during * execution of the custom routine. * * Neither argument passed for validation will be null. * * @param arg_info Information about the argument being validated for use in validation error * messages. * @param expected Pointer to the expected data for the argument. * @param actual Pointer to the actual data passed to the function. * * @return 0 if the argument contained the expected data or 1 if not. */ typedef int (*mock_arg_validator) (const char *arg_info, void *expected, void *actual); /** * Allocate memory and save the data for a pointer argument on a function call. * * @param expected The expectation context for the argument to save. * @param call The calling context for the argument to save. */ typedef void (*mock_arg_alloc) (const struct mock_arg *expected, struct mock_arg *call); /** * Allocate memory and save data to be used for argument expectations. * * @param arg_data The data to copy into the expectation argument. * @param arg_length The length of the data to copy. * @param arg_save The argument buffer to copy the data to. * * @return 0 if the data was successfully copied or an error code. */ typedef int (*mock_arg_alloc_expect) (const void *arg_data, size_t arg_length, void **arg_save); /** * Release memory for saved pointer argument data. * * @param arg The argument data to free. */ typedef void (*mock_arg_free) (void *arg); /** * Copy output data from an expectation to a function argument. * * @param expected The expectation context for the argument to copy. * @param call The calling context to copy into. * @param out_len Buffer space available in the function argument. */ typedef void (*mock_arg_copy) (const struct mock_arg *expected, struct mock_arg *call, size_t out_len); /** * A container for a function argument description. */ struct mock_arg { int64_t value; /**< The expected value of the argument. */ void *ptr_value; /**< Data stored in the pointer argument. */ size_t ptr_value_len; /**< The length of the data stored at the pointer value. */ mock_arg_validator validate; /**< Custom validation routine for the argument. */ const void *out_data; /**< Treat the parameter as an output and return this data. */ size_t out_len; /**< The maximum length of the output data. */ int size_arg; /**< The argument that defines the provided buffer size. */ int save_arg; /**< The ID to use for saving the value of the called argument. */ uint32_t flags; /**< Validation flags for the argument. */ mock_arg_alloc alloc; /**< Allocation function for saving pointer argument data. */ mock_arg_free free; /**< Function to free saved pointer argument data. */ mock_arg_copy copy; /**< Function to copy data into an output paramater. */ mock_arg_free out_free; /**< Function to free the local copy of output data. */ }; /** * Flags to set on a mock argument. */ enum { MOCK_ARG_FLAG_ANY_VALUE = 0x01, /**< The argument value does not matter. */ MOCK_ARG_FLAG_NOT_NULL = 0x02, /**< The argument can be anything as long as it is not NULL (0). */ MOCK_ARG_FLAG_SAVED_VALUE = 0x04, /**< The argument should be validated against a saved value. */ MOCK_ARG_FLAG_ALLOCATED = 0x08, /**< The argument pointer is managed by the mock. */ MOCK_ARG_FLAG_OUT_ALLOCATED = 0x10, /**< The argument output data is managed by the mock. */ MOCK_ARG_FLAG_PTR_PTR = 0x20, /**< The argument is a pointer to a pointer that should be dereferenced. */ MOCK_ARG_FLAG_PTR_PTR_NOT_NULL = 0x40, /**< The pointer referenced by the pointer argument can be anything except NULL (0). */ MOCK_ARG_FLAG_OUT_PTR_PTR = 0x80, /**< The argument output data should be stored at a pointer referenced by another pointer. */ MOCK_ARG_FLAG_GREATER_EQUAL = 0x100, /**< Check that an argument is at least a specific value. */ MOCK_ARG_FLAG_GREATER = 0x200, /**< Check that an argument is larger than a specific value. */ MOCK_ARG_FLAG_LESS_EQUAL = 0x400, /**< Check that an argument is no more than a specific value. */ MOCK_ARG_FLAG_LESS = 0x800, /**< Check that an argument is less than a specific value. */ }; struct mock_call; /** * Defines a callback that can be provided for an expectation to execute custom workflows in * response to a call at run time. * * This action will be called before processing any of the called arguments. This means the called * argument list contains the raw argument values passed to the function and have not been updated * with any output data. * * Do not change any contents of either the expected or called structures. The contents can be * checked as part of the custom workflows, but they must not be modified. * * @param expected The expectation that is being used to validate the current call on the mock. * @param called The context for the actual call on the mock. * * @return This function can return anything that it determines to be appropriate. A return of 0 * causes mock processing for the call to proceed normally. If it returns non-zero, the return * value of this function will be used as the return value from the mock, overriding the return * value specified when the expectation was created. */ typedef int64_t (*mock_call_action) (const struct mock_call *expected, const struct mock_call *called); /** * An expectation for a call to the mock. */ struct mock_call { struct mock_call *next; /**< The next function call in the list. */ const void *func; /**< The expected function. */ const void *instance; /**< The firmware image instance calling the function. */ int argc; /**< The number of arguments. */ struct mock_arg *argv; /**< The arguments to the function. */ int64_t return_val; /**< The value to return for the call. */ mock_call_action action; /**< A custom action to execute while processing the call. */ void *context; /**< User context provided for the custom action. */ }; /** * A container for argument values saved for use by expectations. */ struct mock_save_arg { struct mock_save_arg *next; /**< The next saved argument in the list. */ int id; /**< The ID of the saved argument. */ bool saved; /**< Flag indicating if a value was saved in this container. */ int64_t value; /**< The saved argument value. */ struct mock_save_arg *shared; /**< A link a shared instance for this saved argument. */ }; /** * The base information for a mock instance. */ struct mock { const char *name; /**< The name of the mock instance. */ struct mock_call *expected; /**< The list of expected function calls. */ struct mock_call *exp_tail; /**< The end of the expected list. */ int exp_count; /**< The number of expected calls. */ struct mock_call *called; /**< The list of functions that were called. */ struct mock_call *call_tail; /**< The end of the called functions list. */ int call_count; /**< The number of called functions. */ struct mock_call *next_call; /**< The expected function that will be called next. */ struct mock_save_arg *save; /**< The list of saved argument values. */ int next_id; /**< The next available saved argument ID. */ /** * Get the number of arguments for a mocked function. * * @param func The mocked function. * * @return The number of arguments for the function. */ int (*func_arg_count) (void *func); /** * Function to map a function pointer to a function name. * * @param func The function to map. * * @return The name of the function. */ const char* (*func_name_map) (void *func); /** * Function to map a function argument to a name. * * @param func The function for the argument to map. * @param arg The argument index. * * @return The name of the function argument. */ const char* (*arg_name_map) (void *func, int arg); }; /** * Structure to pass to the mock when setting expectations on a function. */ struct mock_expect_arg { int64_t value; /**< The expected value of the argument. */ size_t ptr_value_len; /**< The length of data that should be validated at a pointer location. */ mock_arg_validator validate; /**< Custom validation routine for the argument. */ int save_arg; /**< The ID of the saved argument entry to use for validation. */ uint32_t flags; /**< Validation flags for the argument. */ mock_arg_alloc alloc; /**< Allocation function for saving pointer argument data. */ mock_arg_free free; /**< Function to free saved pointer argument data. */ mock_arg_alloc_expect copy; /**< Function to make a copy of the argument data. */ }; /** * Expectation that an argument will be a specific value. This should only be used with integer * values. If the argument is a pointer, use MOCK_ARG_PTR instead. */ #define MOCK_ARG(x) ((struct mock_expect_arg) { \ .value = (int64_t) x, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = 0, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument can be any value. */ #define MOCK_ARG_ANY ((struct mock_expect_arg) { \ .value = 0, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_ANY_VALUE, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument will be at least a specific value. This will be treated as a signed * integer value. */ #define MOCK_ARG_AT_LEAST(x) ((struct mock_expect_arg) { \ .value = (int64_t) x, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_GREATER_EQUAL, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument will be larger than a specific value. This will be treated as a * signed integer value. */ #define MOCK_ARG_MORE_THAN(x) ((struct mock_expect_arg) { \ .value = (int64_t) x, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_GREATER, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument will be no larger than a specific value. This will be treated as a * signed integer value. */ #define MOCK_ARG_NO_MORE_THAN(x) ((struct mock_expect_arg) { \ .value = (int64_t) x, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_LESS_EQUAL, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument will be less than a specific value. This will be treated as a * signed integer value. */ #define MOCK_ARG_LESS_THAN(x) ((struct mock_expect_arg) { \ .value = (int64_t) x, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_LESS, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument can be any value expect null or 0. */ #define MOCK_ARG_NOT_NULL ((struct mock_expect_arg) { \ .value = 0, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument will be a specific pointer. */ #define MOCK_ARG_PTR(ptr) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = 0, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument is a pointer to a location that contains the expected data. */ #define MOCK_ARG_PTR_CONTAINS(ptr, len) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = len, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument is a pointer to a location that contains the expected data. The * expected data is stored in a temporary variable that will not be in scope during validation, so * the data is copied into the expectation context. */ #define MOCK_ARG_PTR_CONTAINS_TMP(ptr, len) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = len, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL | MOCK_ARG_FLAG_ALLOCATED, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument value matches that of a saved argument value. */ #define MOCK_ARG_SAVED_ARG(id) ((struct mock_expect_arg) { \ .value = 0, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = id, \ .flags = MOCK_ARG_FLAG_SAVED_VALUE, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument is a pointer to data that will be validated with a custom validation * routine. The validation routine must comply with {@link mock_arg_validator}. */ #define MOCK_ARG_VALIDATOR(func, ptr, len) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = len, \ .validate = func, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument is a pointer to data that will be validated with a custom validation * routine. The validation routine must comply with {@link mock_arg_validator}. The expected data * is stored in a temporary variable that will not be in scope during validation, so the data is * copied into the expectation context. */ #define MOCK_ARG_VALIDATOR_TMP(func, ptr, len) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = len, \ .validate = func, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL | MOCK_ARG_FLAG_ALLOCATED, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument is a pointer to data that will be validated with a custom validation * routine. The validation routine must comply with {@link mock_arg_validator}. The argument data * will be copied and released using the provided allocation and free functions. They can be set to * null to use the default functions. */ #define MOCK_ARG_VALIDATOR_DEEP_COPY(func, ptr, len, save, rel) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = len, \ .validate = func, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL, \ .alloc = save, \ .free = rel, \ .copy = NULL}) /** * Expectation that an argument is a pointer to data that will be validated with a custom validation * routine. The validation routine must comply with {@link mock_arg_validator}. The expected data * is stored in a temporary variable that will not be in scope during validation, so the data is * copied into the expectation context. The argument data will be copied and released using the * provided allocation and free functions. They can be set to null to use the default functions. */ #define MOCK_ARG_VALIDATOR_DEEP_COPY_TMP(func, ptr, len, save, rel, dup) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = len, \ .validate = func, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL | MOCK_ARG_FLAG_ALLOCATED, \ .alloc = save, \ .free = rel, \ .copy = dup}) /** * Expectation that an argument is a pointer to a pointer to a specific location. */ #define MOCK_ARG_PTR_PTR(ptr) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL | MOCK_ARG_FLAG_PTR_PTR, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument is a pointer to a pointer to any location except null or 0. */ #define MOCK_ARG_PTR_PTR_NOT_NULL ((struct mock_expect_arg) { \ .value = 0, \ .ptr_value_len = 0, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL | MOCK_ARG_FLAG_PTR_PTR | MOCK_ARG_FLAG_PTR_PTR_NOT_NULL, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument is a pointer to a pointer to a location that contains the expected * data. */ #define MOCK_ARG_PTR_PTR_CONTAINS(ptr, len) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = len, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL | MOCK_ARG_FLAG_PTR_PTR | MOCK_ARG_FLAG_PTR_PTR_NOT_NULL, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * Expectation that an argument is a pointer to a pointer to a location that contains the expected * data. The expected data is stored in a temporary variable that will not be in scope during * validation, so the data is copied into the expectation context. */ #define MOCK_ARG_PTR_PTR_CONTAINS_TMP(ptr, len) ((struct mock_expect_arg) { \ .value = (int64_t) ((uintptr_t) ptr), \ .ptr_value_len = len, \ .validate = NULL, \ .save_arg = -1, \ .flags = MOCK_ARG_FLAG_NOT_NULL | MOCK_ARG_FLAG_ALLOCATED | MOCK_ARG_FLAG_PTR_PTR | MOCK_ARG_FLAG_PTR_PTR_NOT_NULL, \ .alloc = NULL, \ .free = NULL, \ .copy = NULL}) /** * The return value from an expectation is a pointer. */ #define MOCK_RETURN_PTR(ptr) (int64_t) ((uintptr_t) ptr) int mock_expect (struct mock *mock, void *func_call, void *instance, int64_t return_val, ...); int mock_expect_output (struct mock *mock, int arg, const void *out_data, size_t out_length, int length_arg); int mock_expect_output_tmp (struct mock *mock, int arg, const void *out_data, size_t out_length, int length_arg); int mock_expect_output_ptr (struct mock *mock, int arg, const void *out_data, size_t out_length, int length_arg); int mock_expect_output_ptr_tmp (struct mock *mock, int arg, const void *out_data, size_t out_length, int length_arg); int mock_expect_output_deep_copy (struct mock *mock, int arg, const void *out_data, size_t out_length, mock_arg_copy copy); int mock_expect_output_deep_copy_tmp (struct mock *mock, int arg, const void *out_data, size_t out_length, mock_arg_copy copy, mock_arg_alloc_expect out_copy, mock_arg_free free); int mock_expect_save_arg (struct mock *mock, int arg, int id); int mock_expect_next_save_id (struct mock *mock); int mock_expect_share_save_arg (struct mock *from, int src_id, struct mock *to, int dest_id); int mock_expect_external_action (struct mock *mock, mock_call_action action, void *context); int mock_validate (struct mock *mock); #define MOCK_ERROR(code) ROT_ERROR (ROT_MODULE_MOCK, code) /** * Error codes that can be generated by a mock object. */ enum { MOCK_INVALID_ARGUMENT = MOCK_ERROR (0x00), /**< Input parameter is null or not valid. */ MOCK_NO_MEMORY = MOCK_ERROR (0x01), /**< Memory allocation failed. */ MOCK_NO_EXPECTATION = MOCK_ERROR (0x02), /**< No expectation to modify. */ MOCK_BAD_ARG_INDEX = MOCK_ERROR (0x03), /**< Argument index is not valid for the call. */ MOCK_SAVE_ARG_EXISTS = MOCK_ERROR (0x04), /**< A saved argument already exists for an ID. */ MOCK_NO_SAVE_ARG = MOCK_ERROR (0x05), /**< No saved argument for an ID. */ MOCK_BAD_ARG_LENGTH = MOCK_ERROR (0x06), /**< Argument data is not a valid length. */ }; /** * Helper base struct for defining mock function table */ struct mock_function_table_entry_base { void *func_ptr; /**< Mock function pointer */ size_t arg_count; /**< Number of arguments (not counting "this" pointer) */ const char *func_name; /**< Function name */ }; /** * Abstract helper struct to mimic actual type used for table entries. This struct can't be * instantiated, so it is only used for type casting */ struct mock_function_table_entry { struct mock_function_table_entry_base base; /**< Table entry base */ const char *const arg_names[]; /**< Abstract pointer to the array of argument names */ }; /* Calls for derived mock internal use. */ int mock_init (struct mock *mock); void mock_release (struct mock *mock); void mock_set_name (struct mock *mock, const char *name); struct mock_call* mock_allocate_call (const void *func, const void *instance, size_t args, ...); int64_t mock_return_from_call (struct mock *mock, struct mock_call *call); int mock_function_arg_count (const void *table, size_t table_size, size_t entry_size, void *func); const char* mock_function_arg_name_map (const void *table, size_t table_size, size_t entry_size, void *func, int arg); const char* mock_function_name_map (const void *table, size_t table_size, size_t entry_size, void *func); #define MOCK_ARG_CALL(x) ((int64_t) x) #define MOCK_ARG_PTR_CALL(ptr) ((int64_t) ((uintptr_t) ptr)) #define MOCK_ARG_COUNT(...) (sizeof ((int64_t[]) {__VA_ARGS__}) / sizeof (int64_t)) #define MOCK_VOID_RETURN(mock, func, inst, ...) \ mock_return_from_call (mock, \ mock_allocate_call (func, inst, MOCK_ARG_COUNT (__VA_ARGS__), __VA_ARGS__)) #define MOCK_VOID_RETURN_NO_ARGS(mock, func, inst) \ mock_return_from_call (mock, mock_allocate_call (func, inst, 0)) #define MOCK_RETURN(mock, func, inst, ...) return MOCK_VOID_RETURN (mock, func, inst, __VA_ARGS__) #define MOCK_RETURN_NO_ARGS(mock, func, inst) return MOCK_VOID_RETURN_NO_ARGS (mock, func, inst) #define MOCK_RETURN_CAST(mock, cast, func, inst, ...) \ return (cast) (MOCK_VOID_RETURN (mock, func, inst, __VA_ARGS__)) #define MOCK_RETURN_NO_ARGS_CAST(mock, cast, func, inst) \ return (cast) (MOCK_VOID_RETURN_NO_ARGS (mock, func, inst)) #define MOCK_RETURN_CAST_PTR(mock, cast, func, inst, ...) \ return (cast) ((uintptr_t) (MOCK_VOID_RETURN (mock, func, inst, __VA_ARGS__))) #define MOCK_RETURN_NO_ARGS_CAST_PTR(mock, cast, func, inst) \ return (cast) ((uintptr_t) (MOCK_VOID_RETURN_NO_ARGS (mock, func, inst))) /** * Macro which allows to pass multiple arguments as another macro argument. Used to specify * list of function argument names, for example: * MOCK_FUNCTION_ARGS ("buffer", "buffer_size") * Used in combination with MOCK_FUNCTION macro * * @param "..." List of function argument names */ #define MOCK_FUNCTION_ARGS(...) __VA_ARGS__ /** * Macro to start mock function table definition. The usage should look like: * * MOCK_FUNCTION_TABLE_BEGIN (my_type, 3) * MOCK_FUNCTION (my_type, foo, 2, MOCK_FUNCTION_ARGS ("arg1", "arg2")) * ... * MOCK_FUNCTION_TABLE_END (my_type) * * @param _type Interface type for this mock implementation * @param _max_arg_count Maximum number of function arguments for all functions defined inside * this interface. It has to be provided in order to properly allocate necessary number of entries * to hold each function argument names. */ #define MOCK_FUNCTION_TABLE_BEGIN(_type, _max_arg_count) \ struct { \ struct mock_function_table_entry_base base; \ const char *const arg_names[_max_arg_count]; \ } _type##_mock_funcs[] = { /** * Macro for defining mock function table entries. * * @param _type Interface type for this mock * @param _func_name Interface function * @param _arg_count Number of arguments for this function * @param _arg_names List of argument names passed using MOCK_FUNCTION_ARGS() macro */ #define MOCK_FUNCTION(_type, _func_name, _arg_count, _arg_names) \ { \ .base = { \ .func_ptr = _type##_mock_##_func_name, \ .arg_count = _arg_count, \ .func_name = #_func_name, \ }, \ .arg_names = {_arg_names}, \ }, /** * Macro for finalizing table definition and defining mock interface functions * * @param _type Interface type for this mock */ #define MOCK_FUNCTION_TABLE_END(_type) \ }; \ \ static int _type##_mock_func_arg_count (void *func) \ { \ return mock_function_arg_count (_type##_mock_funcs, ARRAY_SIZE (_type##_mock_funcs), \ sizeof (_type##_mock_funcs[0]), func); \ } \ \ static const char* _type##_mock_arg_name_map (void *func, int arg) \ { \ return mock_function_arg_name_map (_type##_mock_funcs, ARRAY_SIZE (_type##_mock_funcs), \ sizeof (_type##_mock_funcs[0]), func, arg); \ } \ \ static const char* _type##_mock_func_name_map (void *func) \ { \ return mock_function_name_map (_type##_mock_funcs, ARRAY_SIZE (_type##_mock_funcs), \ sizeof (_type##_mock_funcs[0]), func); \ } /** * Macro for initializing mock interface functions. This macro should be used in conjuction * with MOCK_FUNCTION_TABLE_BEGIN(), MOCK_FUNCTION(), MOCK_FUNCTION_TABLE_END() to initialize * mock instance virtual functions * * @param _mock_obj Mock instance to be used initializing mock virtual functions * @param _type Interface type for this mock. Should be the same as used in other MOCK_FUNCTION_xxx * macros */ #define MOCK_INTERFACE_INIT(_mock_obj, _type) \ _mock_obj.func_arg_count = _type##_mock_func_arg_count; \ _mock_obj.func_name_map = _type##_mock_func_name_map; \ _mock_obj.arg_name_map = _type##_mock_arg_name_map; #endif /* MOCK_H_ */