| /* SPDX-License-Identifier: GPL-2.0 */ |
| /* |
| * Mocking API for KUnit. |
| * |
| * Copyright (C) 2018, Google LLC. |
| * Author: Brendan Higgins <brendanhiggins@google.com> |
| */ |
| |
| #ifndef _TEST_MOCK_H |
| #define _TEST_MOCK_H |
| |
| #include <linux/types.h> |
| #include <linux/tracepoint.h> /* For PARAMS(...) */ |
| #include <test/test.h> |
| #include <test/test-stream.h> |
| #include <test/params.h> |
| |
| /** |
| * struct mock_param_matcher - represents a matcher used in a *call expectation* |
| * @match: the function that performs the matching |
| * |
| * The matching function takes a couple of parameters: |
| * |
| * - ``this``: refers to the parent struct |
| * - ``stream``: a &test_stream to which a detailed message should be added as |
| * to why the parameter matches or not |
| * - ``param``: a pointer to the parameter to check for a match |
| * |
| * The matching function should return whether or not the passed parameter |
| * matches. |
| */ |
| struct mock_param_matcher { |
| bool (*match)(struct mock_param_matcher *this, |
| struct test_stream *stream, |
| const void *param); |
| }; |
| |
| #define MOCK_MAX_PARAMS 255 |
| |
| struct mock_matcher { |
| struct mock_param_matcher *matchers[MOCK_MAX_PARAMS]; |
| int num; |
| }; |
| |
| /** |
| * struct mock_action - Represents an action that a mock performs when |
| * expectation is matched |
| * @do_action: the action to perform |
| * |
| * The action function is given some parameters: |
| * |
| * - ``this``: refers to the parent struct |
| * - ``params``: an array of pointers to the params passed into the mocked |
| * method or function. **The class argument is excluded for a mocked class |
| * method.** |
| * - ``len``: size of ``params`` |
| * |
| * The action function returns a pointer to the value that the mocked method |
| * or function should be returning. |
| */ |
| struct mock_action { |
| void *(*do_action)(struct mock_action *this, |
| const void **params, |
| int len); |
| }; |
| |
| /** |
| * struct mock_expectation - represents a *call expectation* on a function. |
| * @action: A &struct mock_action to perform when the function is called. |
| * @max_calls_expected: maximum number of times an expectation may be called. |
| * @min_calls_expected: minimum number of times an expectation may be called. |
| * @retire_on_saturation: no longer match once ``max_calls_expected`` is |
| * reached. |
| * |
| * Represents a *call expectation* on a function created with EXPECT_CALL(). |
| */ |
| struct mock_expectation { |
| struct mock_action *action; |
| int max_calls_expected; |
| int min_calls_expected; |
| bool retire_on_saturation; |
| /* private: internal use only. */ |
| const char *expectation_name; |
| struct list_head node; |
| struct mock_matcher *matcher; |
| struct mock_method *method; |
| int times_called; |
| const char *file_name; |
| int line_no; |
| const char* expectation_text; |
| /* internal list of prerequisites */ |
| struct list_head prerequisites; |
| }; |
| |
| struct mock_expectation_prereq_entry { |
| struct mock_expectation *expectation; |
| struct list_head node; |
| }; |
| |
| struct mock_method { |
| struct list_head node; |
| const char *method_name; |
| const void *method_ptr; |
| struct mock_action *default_action; |
| struct list_head expectations; |
| }; |
| |
| enum mock_type { |
| MOCK_TYPE_NICE, |
| MOCK_TYPE_NAGGY, |
| MOCK_TYPE_STRICT |
| }; |
| |
| struct mock { |
| struct test_post_condition parent; |
| struct test *test; |
| struct list_head methods; |
| enum mock_type type; |
| const void *(*do_expect)(struct mock *mock, |
| const char *method_name, |
| const void *method_ptr, |
| const char * const *param_types, |
| const void **params, |
| int len); |
| }; |
| |
| #define DEFAULT_MOCK_TYPE MOCK_TYPE_NAGGY |
| |
| void mock_init_ctrl(struct test *test, struct mock *mock); |
| |
| void mock_validate_expectations(struct mock *mock); |
| |
| int mock_set_default_action(struct mock *mock, |
| const char *method_name, |
| const void *method_ptr, |
| struct mock_action *action); |
| |
| struct mock_expectation *mock_add_matcher(struct mock *mock, |
| const char *method_name, |
| const void *method_ptr, |
| struct mock_param_matcher *matchers[], |
| int len); |
| |
| struct mock_param_formatter { |
| struct list_head node; |
| const char *type_name; |
| void (*format)(struct mock_param_formatter *formatter, |
| struct test_stream *stream, |
| const void *param); |
| }; |
| |
| void mock_register_formatter(struct mock_param_formatter *formatter); |
| |
| void mock_unregister_formatter(struct mock_param_formatter *formatter); |
| |
| struct mock *mock_get_global_mock(void); |
| |
| #define MOCK(name) name##_mock |
| |
| /** |
| * STRICT_MOCK() - sets the mock to be strict and returns the mock |
| * @mock: the mock |
| * |
| * For an example, see ``The Nice, the Strict, and the Naggy`` under |
| * ``Using KUnit``. |
| */ |
| #define STRICT_MOCK(mock) \ |
| ({ \ |
| mock_get_ctrl(mock)->type = MOCK_TYPE_STRICT; \ |
| mock; \ |
| }) |
| |
| static inline bool is_strict_mock(struct mock *mock) |
| { |
| return mock->type == MOCK_TYPE_STRICT; |
| } |
| |
| /** |
| * NICE_MOCK() - sets the mock to be nice and returns the mock |
| * @mock: the mock |
| * |
| * For an example, see ``The Nice, the Strict, and the Naggy`` under |
| * ``Using KUnit``. |
| */ |
| #define NICE_MOCK(mock) \ |
| ({ \ |
| mock_get_ctrl(mock)->type = MOCK_TYPE_NICE; \ |
| mock; \ |
| }) |
| |
| static inline bool is_nice_mock(struct mock *mock) |
| { |
| return mock->type == MOCK_TYPE_NICE; |
| } |
| |
| /** |
| * NAGGY_MOCK() - sets the mock to be naggy and returns the mock |
| * @mock: the mock |
| * |
| * For an example, see ``The Nice, the Strict, and the Naggy`` under |
| * ``Using KUnit``. |
| */ |
| #define NAGGY_MOCK(mock) \ |
| ({ \ |
| mock_get_ctrl(mock)->type = MOCK_TYPE_NAGGY; \ |
| mock; \ |
| }) |
| |
| static inline bool is_naggy_mock(struct mock *mock) |
| { |
| return mock->type == MOCK_TYPE_NAGGY; |
| } |
| |
| /** |
| * EXPECT_CALL() - Declares a *call expectation* on a mock method or function. |
| * @expectation_call: a mocked method or function with parameters replaced with |
| * matchers. |
| * |
| * Example: |
| * |
| * .. code-block:: c |
| * |
| * // Class to mock. |
| * struct example { |
| * int (*foo)(struct example *, int); |
| * }; |
| * |
| * // Define the mock. |
| * DECLARE_STRUCT_CLASS_MOCK_PREREQS(example); |
| * |
| * DEFINE_STRUCT_CLASS_MOCK(METHOD(foo), CLASS(example), |
| * RETURNS(int), |
| * PARAMS(struct example *, int)); |
| * |
| * static int example_init(struct MOCK(example) *mock_example) |
| * { |
| * struct example *example = mock_get_trgt(mock_example); |
| * |
| * example->foo = foo; |
| * return 0; |
| * } |
| * |
| * DEFINE_STRUCT_CLASS_MOCK_INIT(example, example_init); |
| * |
| * static void foo_example_test_success(struct test *test) |
| * { |
| * struct MOCK(example) *mock_example; |
| * struct example *example = mock_get_trgt(mock_example); |
| * struct mock_expectation *handle; |
| * |
| * mock_example = CONSTRUCT_MOCK(example, test); |
| * |
| * handle = EXPECT_CALL(foo(mock_get_ctrl(mock_example), |
| * int_eq(test, 5))); |
| * handle->action = int_return(test, 2); |
| * |
| * EXPECT_EQ(test, 2, example_bar(example, 5)); |
| * } |
| * |
| * Return: |
| * A &struct mock_expectation representing the call expectation. |
| * allowing additional conditions and actions to be specified. |
| */ |
| #define EXPECT_CALL(expectation_call) \ |
| expect_call_wrapper(__FILE__, __LINE__, \ |
| #expectation_call, mock_master_##expectation_call) |
| |
| static inline struct mock_expectation *expect_call_wrapper( |
| const char *file_name, |
| int line_no, |
| const char* expectation_text, |
| struct mock_expectation *expectation) |
| { |
| expectation->file_name = file_name; |
| expectation->line_no = line_no; |
| expectation->expectation_text = expectation_text; |
| return expectation; |
| } |
| |
| /** |
| * Times() - sets the number of times a method is expected be called with the |
| * matching parameters |
| * @times: the number of times expected |
| * @expectation: the expectation to set |
| * |
| * Return: |
| * the same &struct mock_expectation passed in |
| */ |
| static inline struct mock_expectation *Times( |
| int times, |
| struct mock_expectation *expectation) |
| { |
| expectation->min_calls_expected = times; |
| expectation->max_calls_expected = times; |
| return expectation; |
| } |
| |
| /** |
| * AtLeast() - sets the minimum number of times a method is expected to be |
| * called with matching parameters |
| * @times: the minimum number of times expected |
| * @expectation: the expectation to set |
| * |
| * Return: |
| * the same &struct mock_expectation passed in |
| */ |
| static inline struct mock_expectation *AtLeast( |
| int times, |
| struct mock_expectation *expectation) |
| { |
| expectation->min_calls_expected = times; |
| expectation->max_calls_expected = INT_MAX; |
| return expectation; |
| } |
| |
| /** |
| * AtMost() - sets the maximum number of times a method is expected to be |
| * called with matching parameters |
| * @times: the maximum number of times expected |
| * @expectation: the expectation to set |
| * |
| * Return: |
| * the same &struct mock_expectation passed in |
| */ |
| static inline struct mock_expectation *AtMost( |
| int times, |
| struct mock_expectation *expectation) |
| { |
| expectation->min_calls_expected = 0; |
| expectation->max_calls_expected = times; |
| return expectation; |
| } |
| |
| /** |
| * Between() - sets the minimum and maximum number of times a method is |
| * expected to be called with matching parameters |
| * @min_times: the minimum number of times expected |
| * @max_times: the maximum number of times expected |
| * @expectation: the expectation to set |
| * |
| * Return: |
| * the same &struct mock_expectation passed in |
| */ |
| static inline struct mock_expectation *Between( |
| int min_times, |
| int max_times, |
| struct mock_expectation *expectation) |
| { |
| expectation->min_calls_expected = min_times; |
| expectation->max_calls_expected = max_times; |
| return expectation; |
| } |
| |
| /** |
| * Never() - alias for Times(0) |
| * @expectation: the expectation to set |
| * |
| * Return: |
| * the same &struct mock_expectation passed in |
| */ |
| static inline struct mock_expectation *Never( |
| struct mock_expectation *expectation) |
| { |
| return Times(0, expectation); |
| } |
| |
| /** |
| * RetireOnSaturation() - sets the expectation to retire on saturation |
| * @expectation: the expectation to set |
| * |
| * Return: |
| * the same &struct mock_expectation passed in |
| */ |
| static inline struct mock_expectation *RetireOnSaturation( |
| struct mock_expectation *expectation) |
| { |
| expectation->retire_on_saturation = true; |
| return expectation; |
| } |
| |
| /** |
| * ActionOnMatch() - sets a action of the expectation when matched |
| * @expectation: the expectation to set the action of |
| * @action: action to perform when expectation matches |
| * |
| * Example: |
| * |
| * .. code-block:: c |
| * |
| * ActionOnMatch(EXPECT_CALL(...), INVOKE_REAL(test, ...)); |
| * |
| * Return: |
| * the same &struct mock_expectation passed in |
| */ |
| static inline struct mock_expectation *ActionOnMatch( |
| struct mock_expectation *expectation, |
| struct mock_action *action) |
| { |
| expectation->action = action; |
| return expectation; |
| } |
| |
| /** |
| * Returns() - sets a action of the expectation to return a value |
| * @expectation: the expectation to set the return value of |
| * @return_action: a return action |
| * |
| * Example: |
| * |
| * .. code-block:: c |
| * |
| * Returns(EXPECT_CALL(...), int_return(test, 10)); |
| * |
| * Return: |
| * the same &struct mock_expectation passed in |
| */ |
| static inline struct mock_expectation *Returns( |
| struct mock_expectation *expectation, |
| struct mock_action *return_action) |
| { |
| return ActionOnMatch(expectation, return_action); |
| } |
| |
| /** |
| * InSequence() - defines an order for expectations to be matched |
| * @test: the test, used for internal resource allocations |
| * @first: the first &struct mock_expectation in the sequence |
| * @...: the rest of the expectations in order following |
| * |
| * Example: |
| * |
| * .. code-block:: c |
| * |
| * struct mock_expectation *a = EXPECT_CALL(...); |
| * struct mock_expectation *b = EXPECT_CALL(...); |
| * struct mock_expectation *c = EXPECT_CALL(...); |
| * |
| * InSequence(test, a, b, c); |
| * |
| * Return: |
| * 0 if everything was successful, otherwise a memory allocation error |
| */ |
| #define InSequence(test, first, ...) \ |
| mock_in_sequence(test, first, __VA_ARGS__, 0) |
| |
| int mock_in_sequence(struct test *test, struct mock_expectation *first, ...); |
| |
| #define mock_get_ctrl_internal(mock_object) (&(mock_object)->ctrl) |
| #define mock_get_ctrl(mock_object) mock_get_ctrl_internal(mock_object) |
| |
| #define mock_get_trgt_internal(mock_object) (&(mock_object)->trgt) |
| #define mock_get_trgt(mock_object) mock_get_trgt_internal(mock_object) |
| |
| #define mock_get_test(mock_object) (mock_get_ctrl(mock_object)->test) |
| |
| #define CLASS(struct_name) struct_name |
| #define HANDLE_INDEX(index) index |
| #define METHOD(method_name) method_name |
| #define RETURNS(return_type) return_type |
| /* #define PARAMS(...) __VA_ARGS__ included by linux/tracepoint.h */ |
| |
| #define MOCK_INIT_ID(struct_name) struct_name##mock_init |
| #define REAL_ID(func_name) __real__##func_name |
| #define INVOKE_ID(func_name) __invoke__##func_name |
| |
| #define DECLARE_MOCK_CLIENT(name, return_type, param_types...) \ |
| return_type name(PARAM_LIST_FROM_TYPES(param_types)) |
| |
| #define DECLARE_MOCK_MASTER(name, ctrl_index, param_types...) \ |
| struct mock_expectation *mock_master_##name( \ |
| MATCHER_PARAM_LIST_FROM_TYPES(ctrl_index, \ |
| param_types)); |
| |
| #define DECLARE_MOCK_COMMON(name, handle_index, return_type, param_types...) \ |
| DECLARE_MOCK_CLIENT(name, return_type, param_types); \ |
| DECLARE_MOCK_MASTER(name, handle_index, param_types) |
| |
| #define DECLARE_REDIRECT_MOCKABLE(name, return_type, param_types...) \ |
| return_type REAL_ID(name)(param_types); \ |
| return_type name(param_types); \ |
| void *INVOKE_ID(name)(struct test *test, \ |
| const void *params[], \ |
| int len) |
| |
| #define DECLARE_MOCK_FUNC_CLIENT(name, return_type, param_types...) \ |
| DECLARE_MOCK_CLIENT(name, return_type, param_types) |
| |
| #define DECLARE_MOCK_FUNC_MASTER(name, param_types...) \ |
| DECLARE_MOCK_MASTER(name, MOCK_MAX_PARAMS, param_types) |
| |
| #define DECLARE_STRUCT_CLASS_MOCK_STRUCT(struct_name) \ |
| struct MOCK(struct_name) { \ |
| struct mock ctrl; \ |
| struct struct_name trgt; \ |
| } |
| |
| #define DECLARE_STRUCT_CLASS_MOCK_CONVERTER(struct_name) \ |
| static inline struct mock *from_##struct_name##_to_mock( \ |
| const struct struct_name *trgt) \ |
| { \ |
| return mock_get_ctrl( \ |
| container_of(trgt, \ |
| struct MOCK(struct_name), \ |
| trgt)); \ |
| } |
| |
| /** |
| * DECLARE_STRUCT_CLASS_MOCK_PREREQS() - Create a mock child class |
| * @struct_name: name of the class/struct to be mocked |
| * |
| * Creates a mock child class of ``struct_name`` named |
| * ``struct MOCK(struct_name)`` along with supporting internally used methods. |
| * |
| * See EXPECT_CALL() for example usages. |
| */ |
| #define DECLARE_STRUCT_CLASS_MOCK_PREREQS(struct_name) \ |
| DECLARE_STRUCT_CLASS_MOCK_STRUCT(struct_name); \ |
| DECLARE_STRUCT_CLASS_MOCK_CONVERTER(struct_name) |
| |
| #define DECLARE_STRUCT_CLASS_MOCK_HANDLE_INDEX_INTERNAL(name, \ |
| struct_name, \ |
| handle_index, \ |
| return_type, \ |
| param_types...) \ |
| DECLARE_MOCK_COMMON(name, \ |
| handle_index, \ |
| return_type, \ |
| param_types) |
| |
| #define DECLARE_STRUCT_CLASS_MOCK_HANDLE_INDEX(name, \ |
| struct_name, \ |
| handle_index, \ |
| return_type, \ |
| param_types...) \ |
| DECLARE_STRUCT_CLASS_MOCK_HANDLE_INDEX_INTERNAL(name, \ |
| struct_name, \ |
| handle_index, \ |
| return_type, \ |
| param_types) |
| |
| /** |
| * DECLARE_STRUCT_CLASS_MOCK() |
| * @name: method name |
| * @struct_name: name of the class/struct |
| * @return_type: return type of the method |
| * @param_types: parameters of the method |
| * |
| * Same as DEFINE_STRUCT_CLASS_MOCK(), but only makes header compatible |
| * declarations. |
| */ |
| #define DECLARE_STRUCT_CLASS_MOCK(name, \ |
| struct_name, \ |
| return_type, \ |
| param_types...) \ |
| DECLARE_STRUCT_CLASS_MOCK_HANDLE_INDEX(name, \ |
| struct_name, \ |
| 0, \ |
| return_type, \ |
| param_types) |
| |
| /** |
| * DECLARE_STRUCT_CLASS_MOCK_VOID_RETURN() |
| * @name: method name |
| * @struct_name: name of the class/struct |
| * @param_types: parameters of the method |
| * |
| * Same as DEFINE_STRUCT_CLASS_MOCK_VOID_RETURN(), but only makes header |
| * compatible declarations. |
| */ |
| #define DECLARE_STRUCT_CLASS_MOCK_VOID_RETURN(name, \ |
| struct_name, \ |
| param_types...) \ |
| DECLARE_STRUCT_CLASS_MOCK_HANDLE_INDEX(name, \ |
| struct_name, \ |
| 0, \ |
| void, \ |
| param_types) |
| |
| /** |
| * DECLARE_STRUCT_CLASS_MOCK_INIT() |
| * @struct_name: name of the class/struct |
| * |
| * Same as DEFINE_STRUCT_CLASS_MOCK_INIT(), but only makes header compatible |
| * declarations. |
| */ |
| #define DECLARE_STRUCT_CLASS_MOCK_INIT(struct_name) \ |
| struct MOCK(struct_name) *MOCK_INIT_ID(struct_name)( \ |
| struct test *test) |
| |
| #define DECLARE_VOID_CLASS_MOCK_HANDLE_INDEX_INTERNAL(name, \ |
| handle_index, \ |
| return_type, \ |
| param_types...) \ |
| DECLARE_MOCK_COMMON(name, \ |
| handle_index, \ |
| return_type, \ |
| param_types) |
| |
| #define DECLARE_VOID_CLASS_MOCK_HANDLE_INDEX(name, \ |
| handle_index, \ |
| return_type, \ |
| param_types...) \ |
| DECLARE_VOID_CLASS_MOCK_HANDLE_INDEX_INTERNAL(name, \ |
| handle_index, \ |
| return_type, \ |
| param_types) |
| |
| /** |
| * CONSTRUCT_MOCK() |
| * @struct_name: name of the class |
| * @test: associated test |
| * |
| * Constructs and allocates a test managed ``struct MOCK(struct_name)`` given |
| * the name of the class for which the mock is defined and a test object. |
| * |
| * See EXPECT_CALL() for example usage. |
| */ |
| #define CONSTRUCT_MOCK(struct_name, test) MOCK_INIT_ID(struct_name)(test) |
| |
| #define DECLARE_FUNCTION_MOCK_INTERNAL(name, return_type, param_types...) \ |
| DECLARE_MOCK_FUNC_CLIENT(name, return_type, param_types); \ |
| DECLARE_MOCK_FUNC_MASTER(name, param_types); |
| |
| #define DECLARE_FUNCTION_MOCK(name, return_type, param_types...) \ |
| DECLARE_FUNCTION_MOCK_INTERNAL(name, return_type, param_types) |
| |
| #define DECLARE_FUNCTION_MOCK_VOID_RETURN(name, param_types...) \ |
| DECLARE_FUNCTION_MOCK(name, void, param_types) |
| |
| #define DEFINE_MOCK_CLIENT_COMMON(name, \ |
| handle_index, \ |
| MOCK_SOURCE, \ |
| mock_source_ctx, \ |
| return_type, \ |
| RETURN, \ |
| param_types...) \ |
| return_type name(PARAM_LIST_FROM_TYPES(param_types)) \ |
| { \ |
| struct mock *mock = MOCK_SOURCE(mock_source_ctx, \ |
| handle_index); \ |
| static const char * const param_type_names[] = { \ |
| TYPE_NAMES_FROM_TYPES(handle_index, \ |
| param_types) \ |
| }; \ |
| const void *params[] = { \ |
| PTR_TO_ARG_FROM_TYPES(handle_index, \ |
| param_types) \ |
| }; \ |
| const void *retval; \ |
| \ |
| retval = mock->do_expect(mock, \ |
| #name, \ |
| name, \ |
| param_type_names, \ |
| params, \ |
| ARRAY_SIZE(params)); \ |
| if (!retval) { \ |
| ASSERT_FAILURE(mock->test, "mock " #name \ |
| " expects to return a value," \ |
| " but none is provided."); \ |
| } \ |
| RETURN(return_type, retval); \ |
| } |
| |
| #if IS_ENABLED(CONFIG_TEST) |
| #define DEFINE_INVOKABLE(name, return_type, RETURN_ASSIGN, param_types...) \ |
| void *INVOKE_ID(name)(struct test *test, \ |
| const void *params[], \ |
| int len) { \ |
| return_type *retval; \ |
| \ |
| ASSERT_EQ(test, NUM_VA_ARGS(param_types), len); \ |
| retval = test_kzalloc(test, \ |
| sizeof(*retval), \ |
| GFP_KERNEL); \ |
| ASSERT_NOT_ERR_OR_NULL(test, retval); \ |
| RETURN_ASSIGN() REAL_ID(name)( \ |
| ARRAY_ACCESSORS_FROM_TYPES( \ |
| param_types)); \ |
| return retval; \ |
| } |
| #else |
| #define DEFINE_INVOKABLE(name, return_type, RETURN_ASSIGN, param_types...) |
| #endif |
| |
| #define DEFINE_REDIRECT_MOCKABLE_COMMON(name, \ |
| return_type, \ |
| RETURN_ASSIGN, \ |
| param_types...) \ |
| return_type REAL_ID(name)(param_types); \ |
| return_type name(param_types) __mockable_alias(REAL_ID(name)); \ |
| DEFINE_INVOKABLE(name, return_type, RETURN_ASSIGN, param_types); |
| |
| #define ASSIGN() *retval = |
| |
| /** |
| * DEFINE_REDIRECT_MOCKABLE() |
| * @name: name of the function |
| * @return_type: return type of the function |
| * @param_types: parameter types of the function |
| * |
| * Used to define a function which is *redirect-mockable*, which allows the |
| * function to be mocked and refer to the original definition via |
| * INVOKE_REAL(). |
| * |
| * Example: |
| * |
| * .. code-block:: c |
| * |
| * DEFINE_REDIRECT_MOCKABLE(i2c_add_adapter, |
| * RETURNS(int), PARAMS(struct i2c_adapter *)); |
| * int REAL_ID(i2c_add_adapter)(struct i2c_adapter *adapter) |
| * { |
| * ... |
| * } |
| * |
| * static int aspeed_i2c_test_init(struct test *test) |
| * { |
| * struct mock_param_capturer *adap_capturer; |
| * struct mock_expectation *handle; |
| * struct aspeed_i2c_test *ctx; |
| * int ret; |
| * |
| * ctx = test_kzalloc(test, sizeof(*ctx), GFP_KERNEL); |
| * if (!ctx) |
| * return -ENOMEM; |
| * test->priv = ctx; |
| * |
| * handle = EXPECT_CALL( |
| * i2c_add_adapter(capturer_to_matcher( |
| * adap_capturer))); |
| * handle->action = INVOKE_REAL(test, i2c_add_adapter); |
| * ret = of_fake_probe_platform_by_name(test, |
| * "aspeed-i2c-bus", |
| * "test-i2c-bus"); |
| * if (ret < 0) |
| * return ret; |
| * |
| * ASSERT_PARAM_CAPTURED(test, adap_capturer); |
| * ctx->adap = mock_capturer_get(adap_capturer, |
| * struct i2c_adapter *); |
| * |
| * return 0; |
| * } |
| */ |
| #define DEFINE_REDIRECT_MOCKABLE(name, return_type, param_types...) \ |
| DEFINE_REDIRECT_MOCKABLE_COMMON(name, \ |
| return_type, \ |
| ASSIGN, \ |
| param_types) |
| |
| #define NO_ASSIGN() |
| #define DEFINE_REDIRECT_MOCKABLE_VOID_RETURN(name, param_types) \ |
| DEFINE_REDIRECT_MOCKABLE_COMMON(name, \ |
| void, \ |
| NO_ASSIGN, \ |
| param_types) |
| |
| #define CLASS_MOCK_CLIENT_SOURCE(ctx, handle_index) ctx(arg##handle_index) |
| #define DEFINE_MOCK_METHOD_CLIENT_COMMON(name, \ |
| handle_index, \ |
| mock_converter, \ |
| return_type, \ |
| RETURN, \ |
| param_types...) \ |
| DEFINE_MOCK_CLIENT_COMMON(name, \ |
| handle_index, \ |
| CLASS_MOCK_CLIENT_SOURCE, \ |
| mock_converter, \ |
| return_type, \ |
| RETURN, \ |
| param_types) |
| |
| #define CAST_AND_RETURN(return_type, retval) return *((return_type *) retval) |
| #define NO_RETURN(return_type, retval) |
| |
| #define DEFINE_MOCK_METHOD_CLIENT(name, \ |
| handle_index, \ |
| mock_converter, \ |
| return_type, \ |
| param_types...) \ |
| DEFINE_MOCK_METHOD_CLIENT_COMMON(name, \ |
| handle_index, \ |
| mock_converter, \ |
| return_type, \ |
| CAST_AND_RETURN, \ |
| param_types) |
| |
| #define DEFINE_MOCK_METHOD_CLIENT_VOID_RETURN(name, \ |
| handle_index, \ |
| mock_converter, \ |
| param_types...) \ |
| DEFINE_MOCK_METHOD_CLIENT_COMMON(name, \ |
| handle_index, \ |
| mock_converter, \ |
| void, \ |
| NO_RETURN, \ |
| param_types) |
| |
| #define FUNC_MOCK_SOURCE(ctx, handle_index) mock_get_global_mock() |
| #define DEFINE_MOCK_FUNC_CLIENT_COMMON(name, \ |
| return_type, \ |
| RETURN, \ |
| param_types...) \ |
| DEFINE_MOCK_CLIENT_COMMON(name, \ |
| MOCK_MAX_PARAMS, \ |
| FUNC_MOCK_SOURCE, \ |
| name, \ |
| return_type, \ |
| RETURN, \ |
| param_types) |
| |
| #define DEFINE_MOCK_FUNC_CLIENT(name, return_type, param_types...) \ |
| DEFINE_MOCK_FUNC_CLIENT_COMMON(name, \ |
| return_type, \ |
| CAST_AND_RETURN, \ |
| param_types) |
| |
| #define DEFINE_MOCK_FUNC_CLIENT_VOID_RETURN(name, param_types...) \ |
| DEFINE_MOCK_FUNC_CLIENT_COMMON(name, \ |
| void, \ |
| NO_RETURN, \ |
| param_types) |
| |
| #define DEFINE_MOCK_MASTER_COMMON_INTERNAL(name, \ |
| ctrl_index, \ |
| MOCK_SOURCE, \ |
| param_types...) \ |
| struct mock_expectation *mock_master_##name( \ |
| MATCHER_PARAM_LIST_FROM_TYPES(ctrl_index, \ |
| param_types)) \ |
| { \ |
| struct mock_param_matcher *matchers[] = { \ |
| ARG_NAMES_FROM_TYPES(ctrl_index, param_types) \ |
| }; \ |
| \ |
| return mock_add_matcher(MOCK_SOURCE(ctrl_index), \ |
| #name, \ |
| (const void *) name, \ |
| matchers, \ |
| ARRAY_SIZE(matchers)); \ |
| } |
| #define DEFINE_MOCK_MASTER_COMMON(name, \ |
| ctrl_index, \ |
| MOCK_SOURCE, \ |
| param_types...) \ |
| DEFINE_MOCK_MASTER_COMMON_INTERNAL(name, \ |
| ctrl_index, \ |
| MOCK_SOURCE, \ |
| param_types) |
| |
| #define CLASS_MOCK_MASTER_SOURCE(ctrl_index) arg##ctrl_index |
| #define DEFINE_MOCK_METHOD_MASTER(name, ctrl_index, param_types...) \ |
| DEFINE_MOCK_MASTER_COMMON(name, \ |
| ctrl_index, \ |
| CLASS_MOCK_MASTER_SOURCE, \ |
| param_types) |
| |
| #define FUNC_MOCK_CLIENT_SOURCE(ctrl_index) mock_get_global_mock() |
| #define DEFINE_MOCK_FUNC_MASTER(name, param_types...) \ |
| DEFINE_MOCK_MASTER_COMMON(name, \ |
| MOCK_MAX_PARAMS, \ |
| FUNC_MOCK_CLIENT_SOURCE, \ |
| param_types) |
| |
| #define DEFINE_MOCK_COMMON(name, \ |
| handle_index, \ |
| mock_converter, \ |
| return_type, \ |
| param_types...) \ |
| DEFINE_MOCK_METHOD_CLIENT(name, \ |
| handle_index, \ |
| mock_converter, \ |
| return_type, \ |
| param_types); \ |
| DEFINE_MOCK_METHOD_MASTER(name, handle_index, param_types) |
| |
| #define DEFINE_MOCK_COMMON_VOID_RETURN(name, \ |
| handle_index, \ |
| mock_converter, \ |
| param_types...) \ |
| DEFINE_MOCK_METHOD_CLIENT_VOID_RETURN(name, \ |
| handle_index, \ |
| mock_converter, \ |
| param_types); \ |
| DEFINE_MOCK_METHOD_MASTER(name, handle_index, param_types) |
| |
| #define DEFINE_STRUCT_CLASS_MOCK_HANDLE_INDEX_INTERNAL(name, \ |
| struct_name, \ |
| handle_index, \ |
| return_type, \ |
| param_types...) \ |
| DEFINE_MOCK_COMMON(name, \ |
| handle_index, \ |
| from_##struct_name##_to_mock, \ |
| return_type, param_types) |
| #define DEFINE_STRUCT_CLASS_MOCK_HANDLE_INDEX(name, \ |
| struct_name, \ |
| handle_index, \ |
| return_type, \ |
| param_types...) \ |
| DEFINE_STRUCT_CLASS_MOCK_HANDLE_INDEX_INTERNAL(name, \ |
| struct_name, \ |
| handle_index, \ |
| return_type, \ |
| param_types) |
| |
| #define DEFINE_STRUCT_CLASS_MOCK_HANDLE_INDEX_VOID_RETURN_INTERNAL( \ |
| name, \ |
| struct_name, \ |
| handle_index, \ |
| param_types...) \ |
| DEFINE_MOCK_COMMON_VOID_RETURN(name, \ |
| handle_index, \ |
| from_##struct_name##_to_mock, \ |
| param_types) |
| #define DEFINE_STRUCT_CLASS_MOCK_HANDLE_INDEX_VOID_RETURN(name, \ |
| struct_name, \ |
| handle_index, \ |
| param_types...) \ |
| DEFINE_STRUCT_CLASS_MOCK_HANDLE_INDEX_VOID_RETURN_INTERNAL( \ |
| name, \ |
| struct_name, \ |
| handle_index, \ |
| param_types) |
| |
| /** |
| * DEFINE_STRUCT_CLASS_MOCK() |
| * @name: name of the method |
| * @struct_name: name of the class of which the method belongs |
| * @return_type: return type of the method to be created. **Must not be void.** |
| * @param_types: parameters to method to be created. |
| * |
| * See EXPECT_CALL() for example usage. |
| */ |
| #define DEFINE_STRUCT_CLASS_MOCK(name, \ |
| struct_name, \ |
| return_type, \ |
| param_types...) \ |
| DEFINE_STRUCT_CLASS_MOCK_HANDLE_INDEX(name, \ |
| struct_name, \ |
| 0, \ |
| return_type, \ |
| param_types) |
| |
| /** |
| * DEFINE_STRUCT_CLASS_MOCK_VOID_RETURN() |
| * @name: name of the method |
| * @struct_name: name of the class of which the method belongs |
| * @param_types: parameters to method to be created. |
| * |
| * Same as DEFINE_STRUCT_CLASS_MOCK() except the method has a ``void`` return |
| * type. |
| */ |
| #define DEFINE_STRUCT_CLASS_MOCK_VOID_RETURN(name, struct_name, param_types...)\ |
| DEFINE_STRUCT_CLASS_MOCK_HANDLE_INDEX_VOID_RETURN(name, \ |
| struct_name, \ |
| 0, \ |
| param_types) |
| |
| /** |
| * DEFINE_STRUCT_CLASS_MOCK_INIT() |
| * @struct_name: name of the class |
| * @init_func: a function of type ``int (*)(struct MOCK(struct_name) *)``. This |
| * function is passed a pointer to an allocated, *but not |
| * initialized*, ``struct MOCK(struct_name)``. The job of this user |
| * provided function is to perform remaining initialization. Usually |
| * this entails assigning mock methods to the function pointers in |
| * the parent struct. |
| * |
| * See EXPECT_CALL() for example usage. |
| */ |
| #define DEFINE_STRUCT_CLASS_MOCK_INIT(struct_name, init_func) \ |
| struct MOCK(struct_name) *MOCK_INIT_ID(struct_name)( \ |
| struct test *test) \ |
| { \ |
| struct MOCK(struct_name) *mock_obj; \ |
| \ |
| mock_obj = test_kzalloc(test, \ |
| sizeof(*mock_obj), \ |
| GFP_KERNEL); \ |
| if (!mock_obj) \ |
| return NULL; \ |
| \ |
| mock_init_ctrl(test, mock_get_ctrl(mock_obj)); \ |
| \ |
| if (init_func(mock_obj)) \ |
| return NULL; \ |
| \ |
| return mock_obj; \ |
| } |
| |
| struct MOCK(void) { |
| struct mock ctrl; |
| void *trgt; |
| }; |
| |
| #pragma GCC diagnostic push |
| #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" |
| static inline struct mock *from_void_ptr_to_mock(const void *ptr) |
| { |
| struct MOCK(void) *mock_void_ptr = ptr; |
| |
| return mock_get_ctrl(mock_void_ptr); |
| } |
| #pragma GCC diagnostic pop |
| |
| #define DEFINE_VOID_CLASS_MOCK_HANDLE_INDEX_INTERNAL(name, \ |
| handle_index, \ |
| return_type, \ |
| param_types...) \ |
| DEFINE_MOCK_COMMON(name, \ |
| handle_index, \ |
| from_void_ptr_to_mock, \ |
| return_type, \ |
| param_types) |
| #define DEFINE_VOID_CLASS_MOCK_HANDLE_INDEX(name, \ |
| handle_index, \ |
| return_type, \ |
| param_types...) \ |
| DEFINE_VOID_CLASS_MOCK_HANDLE_INDEX_INTERNAL(name, \ |
| handle_index, \ |
| return_type, \ |
| param_types) |
| |
| DECLARE_STRUCT_CLASS_MOCK_INIT(void); |
| |
| #define DEFINE_FUNCTION_MOCK_INTERNAL(name, return_type, param_types...) \ |
| DEFINE_MOCK_FUNC_CLIENT(name, return_type, param_types); \ |
| DEFINE_MOCK_FUNC_MASTER(name, param_types) |
| |
| /** |
| * DEFINE_FUNCTION_MOCK() |
| * @name: name of the function |
| * @return_type: return type of the function |
| * @...: parameter types of the function |
| * |
| * Same as DEFINE_STRUCT_CLASS_MOCK() except can be used to mock any function |
| * declared %__mockable or DEFINE_REDIRECT_MOCKABLE() |
| */ |
| #define DEFINE_FUNCTION_MOCK(name, return_type, param_types...) \ |
| DEFINE_FUNCTION_MOCK_INTERNAL(name, return_type, param_types) |
| |
| #define DEFINE_FUNCTION_MOCK_VOID_RETURN_INTERNAL(name, param_types...) \ |
| DEFINE_MOCK_FUNC_CLIENT_VOID_RETURN(name, param_types); \ |
| DEFINE_MOCK_FUNC_MASTER(name, param_types) |
| |
| /** |
| * DEFINE_FUNCTION_MOCK_VOID_RETURN() |
| * @name: name of the function |
| * @...: parameter types of the function |
| * |
| * Same as DEFINE_FUNCTION_MOCK() except the method has a ``void`` return |
| * type. |
| */ |
| #define DEFINE_FUNCTION_MOCK_VOID_RETURN(name, param_types...) \ |
| DEFINE_FUNCTION_MOCK_VOID_RETURN_INTERNAL(name, param_types) |
| |
| #if IS_ENABLED(CONFIG_TEST) |
| |
| /** |
| * __mockable - A function decorator that allows the function to be mocked. |
| * |
| * Example: |
| * |
| * .. code-block:: c |
| * |
| * int __mockable example(int arg) { ... } |
| */ |
| #define __mockable __weak |
| #define __mockable_alias(id) __weak __alias(id) |
| |
| /** |
| * __visible_for_testing - Makes a static function visible when testing. |
| * |
| * A macro that replaces the `static` specifier on functions and global |
| * variables that is static when compiled normally and visible when compiled for |
| * tests. |
| */ |
| #define __visible_for_testing |
| #else |
| #define __mockable |
| #define __mockable_alias(id) __alias(id) |
| #define __visible_for_testing static |
| #endif |
| |
| #define CONVERT_TO_ACTUAL_TYPE(type, ptr) (*((type *) ptr)) |
| |
| /** |
| * DOC: Built In Matchers |
| * |
| * These are the matchers that can be used when matching arguments in |
| * :c:func:`EXPECT_CALL` (more can be defined manually). |
| * |
| * For example, there's a matcher that matches any arguments: |
| * |
| * .. code-block:: c |
| * |
| * struct mock_param_matcher *any(struct test *test); |
| * |
| * There are matchers for integers based on the binary condition: |
| * |
| * * eq: equals to |
| * * ne: not equal to |
| * * lt: less than |
| * * le: less than or equal to |
| * * gt: greater than |
| * * ge: greater than or equal to |
| * |
| * .. code-block:: c |
| * |
| * struct mock_param_matcher *int_eq(struct test *test, int expected); |
| * struct mock_param_matcher *int_ne(struct test *test, int expected); |
| * struct mock_param_matcher *int_lt(struct test *test, int expected); |
| * struct mock_param_matcher *int_le(struct test *test, int expected); |
| * struct mock_param_matcher *int_gt(struct test *test, int expected); |
| * struct mock_param_matcher *int_ge(struct test *test, int expected); |
| * |
| * For a detailed list, please see |
| * ``include/linux/mock.h``. |
| */ |
| |
| /* Matches any argument */ |
| struct mock_param_matcher *any(struct test *test); |
| |
| /* |
| * Matches different types of integers, the argument is compared to the |
| * `expected` field, based on the comparison defined. |
| */ |
| struct mock_param_matcher *u8_eq(struct test *test, u8 expected); |
| struct mock_param_matcher *u8_ne(struct test *test, u8 expected); |
| struct mock_param_matcher *u8_le(struct test *test, u8 expected); |
| struct mock_param_matcher *u8_lt(struct test *test, u8 expected); |
| struct mock_param_matcher *u8_ge(struct test *test, u8 expected); |
| struct mock_param_matcher *u8_gt(struct test *test, u8 expected); |
| |
| struct mock_param_matcher *u16_eq(struct test *test, u16 expected); |
| struct mock_param_matcher *u16_ne(struct test *test, u16 expected); |
| struct mock_param_matcher *u16_le(struct test *test, u16 expected); |
| struct mock_param_matcher *u16_lt(struct test *test, u16 expected); |
| struct mock_param_matcher *u16_ge(struct test *test, u16 expected); |
| struct mock_param_matcher *u16_gt(struct test *test, u16 expected); |
| |
| struct mock_param_matcher *u32_eq(struct test *test, u32 expected); |
| struct mock_param_matcher *u32_ne(struct test *test, u32 expected); |
| struct mock_param_matcher *u32_le(struct test *test, u32 expected); |
| struct mock_param_matcher *u32_lt(struct test *test, u32 expected); |
| struct mock_param_matcher *u32_ge(struct test *test, u32 expected); |
| struct mock_param_matcher *u32_gt(struct test *test, u32 expected); |
| |
| struct mock_param_matcher *u64_eq(struct test *test, u64 expected); |
| struct mock_param_matcher *u64_ne(struct test *test, u64 expected); |
| struct mock_param_matcher *u64_le(struct test *test, u64 expected); |
| struct mock_param_matcher *u64_lt(struct test *test, u64 expected); |
| struct mock_param_matcher *u64_ge(struct test *test, u64 expected); |
| struct mock_param_matcher *u64_gt(struct test *test, u64 expected); |
| |
| struct mock_param_matcher *char_eq(struct test *test, char expected); |
| struct mock_param_matcher *char_ne(struct test *test, char expected); |
| struct mock_param_matcher *char_le(struct test *test, char expected); |
| struct mock_param_matcher *char_lt(struct test *test, char expected); |
| struct mock_param_matcher *char_ge(struct test *test, char expected); |
| struct mock_param_matcher *char_gt(struct test *test, char expected); |
| |
| struct mock_param_matcher *uchar_eq(struct test *test, unsigned char expected); |
| struct mock_param_matcher *uchar_ne(struct test *test, unsigned char expected); |
| struct mock_param_matcher *uchar_le(struct test *test, unsigned char expected); |
| struct mock_param_matcher *uchar_lt(struct test *test, unsigned char expected); |
| struct mock_param_matcher *uchar_ge(struct test *test, unsigned char expected); |
| struct mock_param_matcher *uchar_gt(struct test *test, unsigned char expected); |
| |
| struct mock_param_matcher *schar_eq(struct test *test, signed char expected); |
| struct mock_param_matcher *schar_ne(struct test *test, signed char expected); |
| struct mock_param_matcher *schar_le(struct test *test, signed char expected); |
| struct mock_param_matcher *schar_lt(struct test *test, signed char expected); |
| struct mock_param_matcher *schar_ge(struct test *test, signed char expected); |
| struct mock_param_matcher *schar_gt(struct test *test, signed char expected); |
| |
| struct mock_param_matcher *short_eq(struct test *test, short expected); |
| struct mock_param_matcher *short_ne(struct test *test, short expected); |
| struct mock_param_matcher *short_le(struct test *test, short expected); |
| struct mock_param_matcher *short_lt(struct test *test, short expected); |
| struct mock_param_matcher *short_ge(struct test *test, short expected); |
| struct mock_param_matcher *short_gt(struct test *test, short expected); |
| |
| struct mock_param_matcher *ushort_eq(struct test *test, |
| unsigned short expected); |
| struct mock_param_matcher *ushort_ne(struct test *test, |
| unsigned short expected); |
| struct mock_param_matcher *ushort_le(struct test *test, |
| unsigned short expected); |
| struct mock_param_matcher *ushort_lt(struct test *test, |
| unsigned short expected); |
| struct mock_param_matcher *ushort_ge(struct test *test, |
| unsigned short expected); |
| struct mock_param_matcher *ushort_gt(struct test *test, |
| unsigned short expected); |
| |
| struct mock_param_matcher *int_eq(struct test *test, int expected); |
| struct mock_param_matcher *int_ne(struct test *test, int expected); |
| struct mock_param_matcher *int_lt(struct test *test, int expected); |
| struct mock_param_matcher *int_le(struct test *test, int expected); |
| struct mock_param_matcher *int_gt(struct test *test, int expected); |
| struct mock_param_matcher *int_ge(struct test *test, int expected); |
| |
| struct mock_param_matcher *uint_eq(struct test *test, unsigned int expected); |
| struct mock_param_matcher *uint_ne(struct test *test, unsigned int expected); |
| struct mock_param_matcher *uint_lt(struct test *test, unsigned int expected); |
| struct mock_param_matcher *uint_le(struct test *test, unsigned int expected); |
| struct mock_param_matcher *uint_gt(struct test *test, unsigned int expected); |
| struct mock_param_matcher *uint_ge(struct test *test, unsigned int expected); |
| |
| struct mock_param_matcher *long_eq(struct test *test, long expected); |
| struct mock_param_matcher *long_ne(struct test *test, long expected); |
| struct mock_param_matcher *long_le(struct test *test, long expected); |
| struct mock_param_matcher *long_lt(struct test *test, long expected); |
| struct mock_param_matcher *long_ge(struct test *test, long expected); |
| struct mock_param_matcher *long_gt(struct test *test, long expected); |
| |
| struct mock_param_matcher *ulong_eq(struct test *test, unsigned long expected); |
| struct mock_param_matcher *ulong_ne(struct test *test, unsigned long expected); |
| struct mock_param_matcher *ulong_le(struct test *test, unsigned long expected); |
| struct mock_param_matcher *ulong_lt(struct test *test, unsigned long expected); |
| struct mock_param_matcher *ulong_ge(struct test *test, unsigned long expected); |
| struct mock_param_matcher *ulong_gt(struct test *test, unsigned long expected); |
| |
| struct mock_param_matcher *longlong_eq(struct test *test, long long expected); |
| struct mock_param_matcher *longlong_ne(struct test *test, long long expected); |
| struct mock_param_matcher *longlong_le(struct test *test, long long expected); |
| struct mock_param_matcher *longlong_lt(struct test *test, long long expected); |
| struct mock_param_matcher *longlong_ge(struct test *test, long long expected); |
| struct mock_param_matcher *longlong_gt(struct test *test, long long expected); |
| |
| struct mock_param_matcher *ulonglong_eq(struct test *test, |
| unsigned long long expected); |
| struct mock_param_matcher *ulonglong_ne(struct test *test, |
| unsigned long long expected); |
| struct mock_param_matcher *ulonglong_le(struct test *test, |
| unsigned long long expected); |
| struct mock_param_matcher *ulonglong_lt(struct test *test, |
| unsigned long long expected); |
| struct mock_param_matcher *ulonglong_ge(struct test *test, |
| unsigned long long expected); |
| struct mock_param_matcher *ulonglong_gt(struct test *test, |
| unsigned long long expected); |
| |
| /* matches booleans. */ |
| struct mock_param_matcher *bool_eq(struct test *test, bool expected); |
| struct mock_param_matcher *bool_ne(struct test *test, bool expected); |
| |
| /* Matches pointers. */ |
| struct mock_param_matcher *ptr_eq(struct test *test, void *expected); |
| struct mock_param_matcher *ptr_ne(struct test *test, void *expected); |
| struct mock_param_matcher *ptr_lt(struct test *test, void *expected); |
| struct mock_param_matcher *ptr_le(struct test *test, void *expected); |
| struct mock_param_matcher *ptr_gt(struct test *test, void *expected); |
| struct mock_param_matcher *ptr_ge(struct test *test, void *expected); |
| |
| /* Matches memory sections and strings. */ |
| struct mock_param_matcher *memeq(struct test *test, |
| const void *buf, |
| size_t size); |
| struct mock_param_matcher *streq(struct test *test, const char *str); |
| |
| struct mock_param_matcher *str_contains(struct test *test, const char *needle); |
| |
| /* Matches var-arg arguments. */ |
| struct mock_param_matcher *va_format_cmp(struct test *test, |
| struct mock_param_matcher *fmt_matcher, |
| struct mock_param_matcher *va_matcher); |
| |
| /* Compound matchers */ |
| struct mock_param_matcher *and(struct test *test, |
| struct mock_param_matcher *left_matcher, |
| struct mock_param_matcher *right_matcher); |
| struct mock_param_matcher *or(struct test *test, |
| struct mock_param_matcher *left_matcher, |
| struct mock_param_matcher *right_matcher); |
| struct mock_param_matcher *not(struct test *test, |
| struct mock_param_matcher *inner_matcher); |
| struct mock_action *bool_return(struct test *test, bool ret); |
| struct mock_action *u8_return(struct test *test, u8 ret); |
| struct mock_action *u16_return(struct test *test, u16 ret); |
| struct mock_action *u32_return(struct test *test, u32 ret); |
| struct mock_action *u64_return(struct test *test, u64 ret); |
| struct mock_action *char_return(struct test *test, char ret); |
| struct mock_action *uchar_return(struct test *test, unsigned char ret); |
| struct mock_action *schar_return(struct test *test, signed char ret); |
| struct mock_action *short_return(struct test *test, short ret); |
| struct mock_action *ushort_return(struct test *test, unsigned short ret); |
| struct mock_action *int_return(struct test *test, int ret); |
| struct mock_action *uint_return(struct test *test, unsigned int ret); |
| struct mock_action *long_return(struct test *test, long ret); |
| struct mock_action *ulong_return(struct test *test, unsigned long ret); |
| struct mock_action *longlong_return(struct test *test, long long ret); |
| struct mock_action *ulonglong_return(struct test *test, unsigned long long ret); |
| struct mock_action *ptr_return(struct test *test, void *ret); |
| |
| /** |
| * struct mock_struct_matcher_entry - composed with other &struct |
| * mock_struct_matcher_entry to make a |
| * &struct struct_matcher |
| * @member_offset: offset of this member |
| * @matcher: matcher for this particular member |
| * |
| * This is used for struct_cmp() matchers. |
| */ |
| struct mock_struct_matcher_entry { |
| size_t member_offset; |
| struct mock_param_matcher *matcher; |
| }; |
| |
| static inline void init_mock_struct_matcher_entry_internal( |
| struct mock_struct_matcher_entry *entry, |
| size_t offset, |
| struct mock_param_matcher *matcher) |
| { |
| entry->member_offset = offset; |
| entry->matcher = matcher; |
| } |
| |
| /** |
| * INIT_MOCK_STRUCT_MATCHER_ENTRY() |
| * @entry: the &struct mock_struct_matcher_entry to initialize |
| * @type: the struct being matched |
| * @member: the member of the struct being matched, used to calculate the offset |
| * @matcher: matcher to match that member |
| * |
| * Initializes ``entry`` to match ``type->member`` with ``matcher``. |
| */ |
| #define INIT_MOCK_STRUCT_MATCHER_ENTRY(entry, type, member, matcher) \ |
| init_mock_struct_matcher_entry_internal(entry, \ |
| offsetof(type, member),\ |
| matcher) |
| |
| static inline void INIT_MOCK_STRUCT_MATCHER_ENTRY_LAST( |
| struct mock_struct_matcher_entry *entry) |
| { |
| entry->matcher = NULL; |
| } |
| |
| struct mock_param_matcher *struct_cmp( |
| struct test *test, |
| const char *struct_name, |
| struct mock_struct_matcher_entry *entries); |
| |
| /** |
| * struct mock_param_capturer - used to capture parameter when matching |
| * |
| * Use the associated helper macros to access relevant fields. |
| * Example: |
| * |
| * .. code-block::c |
| * |
| * static int some_test(struct test *test) |
| * { |
| * // imagine a mocked function: int add(int a, int b) |
| * struct mock_param_capturer *capturer = |
| * mock_int_capturer_create(test, any(test)); |
| * EXPECT_CALL(add(any(test), capturer_to_matcher(capturer))); |
| * ASSERT_PARAM_CAPTURED(test, capturer); |
| * |
| * int captured_value = mock_capturer_get(capturer, int); |
| * } |
| */ |
| struct mock_param_capturer { |
| /* private: internal use only. */ |
| struct mock_param_matcher matcher; |
| struct mock_param_matcher *child_matcher; |
| void *(*capture_param)(struct test *test, const void *param); |
| void *captured_param; |
| }; |
| |
| struct mock_param_capturer *mock_param_capturer_create( |
| struct test *test, |
| struct mock_param_matcher *child_matcher, |
| void *(*capture_param)(struct test *, const void *)); |
| |
| /** |
| * mock_int_capturer_create() - creates a int parameter capturer |
| * @test: associated test |
| * @child_matcher: matcher used to match the integer |
| * |
| * The capturer will capture the value if the matcher is satisfied. |
| */ |
| struct mock_param_capturer *mock_int_capturer_create( |
| struct test *test, struct mock_param_matcher *child_matcher); |
| |
| /** |
| * mock_int_capturer_create() - creates a generic pointer parameter capturer |
| * @test: associated test |
| * @child_matcher: matcher used to match the pointer |
| * |
| * The capturer will capture the value if the matcher is satisfied |
| */ |
| struct mock_param_capturer *mock_ptr_capturer_create( |
| struct test *test, struct mock_param_matcher *child_matcher); |
| |
| /** |
| * capturer_to_matcher() |
| * @capturer: the param capturer |
| * |
| * Use this function when passing a capturer into an EXPECT_CALL() where a |
| * matcher would be expected. See the example for &struct mock_param_capturer. |
| */ |
| #define capturer_to_matcher(capturer) (&(capturer)->matcher) |
| |
| /** |
| * ASSERT_PARAM_CAPTURED(): Asserts that the capturer has captured a parameter. |
| * @test: the associated test |
| * @capturer: the param capturer |
| * |
| * See &struct mock_param_capturer for an example. |
| */ |
| #define ASSERT_PARAM_CAPTURED(test, capturer) \ |
| ASSERT(test, \ |
| !IS_ERR_OR_NULL((capturer)->captured_param), \ |
| "Asserted " #capturer " captured param, but did not.") |
| |
| /** |
| * mock_capturer_get(): Returns the value captured by ``capturer`` |
| * @capturer: the param capturer |
| * @type: the type of the value |
| * |
| * See &struct mock_param_capturer for an example. |
| */ |
| #define mock_capturer_get(capturer, type) \ |
| CONVERT_TO_ACTUAL_TYPE(type, (capturer)->captured_param) |
| |
| struct mock_action *invoke(struct test *test, |
| void *(*invokable)(struct test *, |
| const void *params[], |
| int len)); |
| |
| /** |
| * INVOKE_REAL() |
| * @test: associated test |
| * @func_name: name of the function |
| * |
| * See DEFINE_REDIRECT_MOCKABLE() for an example. |
| * |
| * Return: &struct mock_action that makes the associated mock method or function |
| * call the original function definition of a redirect-mockable |
| * function. |
| */ |
| #define INVOKE_REAL(test, func_name) invoke(test, INVOKE_ID(func_name)) |
| |
| struct mock_struct_formatter_entry { |
| size_t member_offset; |
| struct mock_param_formatter *formatter; |
| }; |
| |
| static inline void init_mock_struct_formatter_entry_internal( |
| struct mock_struct_formatter_entry *entry, |
| size_t offset, |
| struct mock_param_formatter *formatter) |
| { |
| entry->member_offset = offset; |
| entry->formatter = formatter; |
| } |
| |
| #define INIT_MOCK_STRUCT_FORMATTER_ENTRY(entry, type, member, formatter) \ |
| init_mock_struct_formatter_entry_internal(entry, \ |
| offsetof(type, \ |
| member), \ |
| formatter) |
| |
| static inline void INIT_MOCK_STRUCT_FORMATTER_ENTRY_LAST( |
| struct mock_struct_formatter_entry *entry) |
| { |
| entry->formatter = NULL; |
| } |
| |
| struct mock_param_formatter *mock_struct_formatter( |
| struct test *test, |
| const char *struct_name, |
| struct mock_struct_formatter_entry *entries); |
| |
| struct mock_param_formatter *mock_find_formatter(const char *type_name); |
| |
| #define FORMATTER_FROM_TYPE(type) mock_find_formatter(#type) |
| |
| extern struct mock_param_formatter unknown_formatter[]; |
| |
| #endif /* _TEST_MOCK_H */ |