1117 lines
35 KiB
C
1117 lines
35 KiB
C
|
// SPDX-License-Identifier: GPL-2.0
|
||
|
/*
|
||
|
* KUnit test for mock.h.
|
||
|
*
|
||
|
* Copyright (C) 2018, Google LLC.
|
||
|
* Author: Brendan Higgins <brendanhiggins@google.com>
|
||
|
*/
|
||
|
|
||
|
#include <test/test.h>
|
||
|
#include <test/mock.h>
|
||
|
|
||
|
#include "test-mock.h"
|
||
|
|
||
|
struct mock_test_context {
|
||
|
struct MOCK(KUNIT_T) *mock_test;
|
||
|
struct mock *mock;
|
||
|
};
|
||
|
|
||
|
static void mock_test_do_expect_basic(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
int param0 = 5, param1 = -4;
|
||
|
static const char * const two_param_types[] = {"int", "int"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
struct mock_param_matcher *matchers_any_two[] = {any(trgt), any(trgt)};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers_any_two,
|
||
|
ARRAY_SIZE(matchers_any_two));
|
||
|
expectation->action = int_return(trgt, 5);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
two_param_types,
|
||
|
two_params,
|
||
|
ARRAY_SIZE(two_params));
|
||
|
ASSERT_NOT_ERR_OR_NULL(test, ret);
|
||
|
EXPECT_EQ(test, 5, *((int *) ret));
|
||
|
EXPECT_EQ(test, 1, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
static void mock_test_ptr_eq(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
void *param0 = ctx, *param1 = trgt;
|
||
|
static const char * const two_param_types[] = {"void *", "void *"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
struct mock_param_matcher *matchers_two_ptrs[] = {
|
||
|
ptr_eq(trgt, param0), ptr_eq(trgt, param1)
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers_two_ptrs,
|
||
|
ARRAY_SIZE(matchers_two_ptrs));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
two_param_types,
|
||
|
two_params,
|
||
|
ARRAY_SIZE(two_params));
|
||
|
ASSERT_NOT_ERR_OR_NULL(test, ret);
|
||
|
EXPECT_EQ(test, 1, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
static void mock_test_ptr_eq_not_equal(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
void *param0 = ctx, *param1 = trgt;
|
||
|
static const char * const two_param_types[] = {"void *", "void *"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
struct mock_param_matcher *matchers_two_ptrs[] = {
|
||
|
ptr_eq(trgt, param0), ptr_eq(trgt, param1 - 1)
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers_two_ptrs,
|
||
|
ARRAY_SIZE(matchers_two_ptrs));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
two_param_types,
|
||
|
two_params,
|
||
|
ARRAY_SIZE(two_params));
|
||
|
EXPECT_FALSE(test, ret);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* In order for us to be able to rely on EXPECT_CALL to validate other behavior,
|
||
|
* we need to test that unsatisfied EXPECT_CALL causes a test failure.
|
||
|
*/
|
||
|
static void mock_test_failed_expect_call_fails_test(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
/* mock is a pretend mock belonging to our mocked_test */
|
||
|
|
||
|
/* Put an expectation on mocked mock */
|
||
|
EXPECT_CALL(fail(mock, any(mock_get_trgt(mock_test))));
|
||
|
|
||
|
/*
|
||
|
* Expect that mock_test will fail because the above won't be satisfied
|
||
|
*/
|
||
|
EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test)));
|
||
|
|
||
|
/*
|
||
|
* Validate expectations of mocked mock, which should fail mocked test
|
||
|
*/
|
||
|
mock_validate_expectations(mock);
|
||
|
|
||
|
/* Validate mock_test's expectations, that is, it should have failed */
|
||
|
mock_validate_expectations(mock_get_ctrl(mock_test));
|
||
|
EXPECT_FALSE(test, mock_get_trgt(mock_test)->success);
|
||
|
}
|
||
|
|
||
|
static void mock_test_do_expect_default_return(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = NICE_MOCK(ctx->mock_test);
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
int param0 = 5, param1 = -5;
|
||
|
static const char * const two_param_types[] = {"int", "int"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
int_eq(trgt, 5),
|
||
|
int_eq(trgt, -4)
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"test_printk",
|
||
|
test_printk,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 5);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
EXPECT_FALSE(test, mock_set_default_action(mock,
|
||
|
"test_printk",
|
||
|
test_printk,
|
||
|
int_return(trgt, -4)));
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"test_printk",
|
||
|
test_printk,
|
||
|
two_param_types,
|
||
|
two_params,
|
||
|
ARRAY_SIZE(two_params));
|
||
|
ASSERT_NOT_ERR_OR_NULL(test, ret);
|
||
|
EXPECT_EQ(test, -4, *((int *) ret));
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* DOC: Testing the failure condition of different mock types.
|
||
|
*
|
||
|
* The following tests will test the behaviour of expectations under different
|
||
|
* conditions. For example, what happens when an expectation:
|
||
|
* - is not satisfied at the end of the test
|
||
|
* - is fulfilled but the expected function is called again
|
||
|
* - a function is called without expectations set on it
|
||
|
*
|
||
|
* For each of these conditions, there may be variations between the different
|
||
|
* types of mocks: nice mocks, naggy mocks (the default) and strict mocks.
|
||
|
*
|
||
|
* More information about these mocks can be found in the kernel documentation
|
||
|
* under Documentation/test/api/class-and-function-mocking
|
||
|
*/
|
||
|
|
||
|
/* Method called on strict mock with no expectations will fail */
|
||
|
static void mock_test_strict_no_expectations_will_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
int param0 = 5, param1 = -5;
|
||
|
static const char * const two_param_types[] = {"int", "int"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
struct mock_expectation *expectation;
|
||
|
|
||
|
mock->type = MOCK_TYPE_STRICT;
|
||
|
|
||
|
mock_set_default_action(mock,
|
||
|
"test_printk",
|
||
|
test_printk,
|
||
|
int_return(trgt, -4));
|
||
|
|
||
|
expectation = EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test)));
|
||
|
|
||
|
mock->do_expect(mock, "test_printk", test_printk, two_param_types,
|
||
|
two_params, ARRAY_SIZE(two_params));
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Method called on naggy mock with no expectations will not fail, but will show
|
||
|
* a warning message
|
||
|
*/
|
||
|
static void mock_test_naggy_no_expectations_no_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
int param0 = 5, param1 = -5;
|
||
|
static const char * const two_param_types[] = {"int", "int"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
struct mock_expectation *expectation;
|
||
|
|
||
|
mock->type = MOCK_TYPE_NAGGY;
|
||
|
|
||
|
mock_set_default_action(mock, "test_printk", test_printk,
|
||
|
int_return(trgt, -4));
|
||
|
|
||
|
expectation = Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test),
|
||
|
any(test))));
|
||
|
|
||
|
EXPECT_CALL(mock_vprintk(mock_get_ctrl(mock_test), any(test),
|
||
|
va_format_cmp(test, str_contains(test,
|
||
|
"Method was called with no expectations declared"),
|
||
|
any(test))));
|
||
|
|
||
|
mock->do_expect(mock,
|
||
|
"test_printk",
|
||
|
test_printk,
|
||
|
two_param_types,
|
||
|
two_params,
|
||
|
ARRAY_SIZE(two_params));
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
/* Method called on nice mock with no expectations will do nothing. */
|
||
|
static void mock_test_nice_no_expectations_do_nothing(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
int param0 = 5, param1 = -5;
|
||
|
static const char * const two_param_types[] = {"int", "int"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
struct mock_expectation *expectation;
|
||
|
|
||
|
mock->type = MOCK_TYPE_NICE;
|
||
|
|
||
|
mock_set_default_action(mock,
|
||
|
"test_printk",
|
||
|
test_printk,
|
||
|
int_return(trgt, -4));
|
||
|
|
||
|
expectation = Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test),
|
||
|
any(test))));
|
||
|
|
||
|
expectation = Never(EXPECT_CALL(mock_vprintk(mock_get_ctrl(mock_test),
|
||
|
any(test),
|
||
|
any(test))));
|
||
|
|
||
|
mock->do_expect(mock,
|
||
|
"test_printk",
|
||
|
test_printk,
|
||
|
two_param_types,
|
||
|
two_params,
|
||
|
ARRAY_SIZE(two_params));
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
/* Test that method called on a mock (of any type) with no matching expectations
|
||
|
* will fail test and print all the tried expectations.
|
||
|
*/
|
||
|
static void
|
||
|
run_method_called_but_no_matching_expectation_test(struct KUNIT_T *test,
|
||
|
enum mock_type mock_type)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
int param0 = 5, param1 = -5;
|
||
|
static const char * const two_param_types[] = {"int", "int"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
struct mock_expectation *handle;
|
||
|
struct mock_param_matcher *two_matchers[] = {
|
||
|
int_eq(trgt, 100),
|
||
|
int_eq(trgt, 100)
|
||
|
};
|
||
|
mock_add_matcher(mock, "test_printk", test_printk, two_matchers,
|
||
|
ARRAY_SIZE(two_matchers));
|
||
|
handle = EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test)));
|
||
|
|
||
|
mock->type = mock_type;
|
||
|
|
||
|
mock->do_expect(mock, "test_printk", test_printk, two_param_types,
|
||
|
two_params, ARRAY_SIZE(two_params));
|
||
|
}
|
||
|
|
||
|
static void mock_test_naggy_no_matching_expectations_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
run_method_called_but_no_matching_expectation_test(test,
|
||
|
MOCK_TYPE_NAGGY);
|
||
|
}
|
||
|
|
||
|
static void mock_test_strict_no_matching_expectations_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
run_method_called_but_no_matching_expectation_test(test,
|
||
|
MOCK_TYPE_STRICT);
|
||
|
}
|
||
|
|
||
|
static void mock_test_nice_no_matching_expectations_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
run_method_called_but_no_matching_expectation_test(test,
|
||
|
MOCK_TYPE_NICE);
|
||
|
}
|
||
|
|
||
|
static void mock_test_mock_validate_expectations(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
int_eq(trgt, 5),
|
||
|
int_eq(trgt, -4)
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
|
||
|
EXPECT_EQ(test, mock_get_trgt(mock_test), mock->test);
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"test_printk",
|
||
|
test_printk,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->times_called = 0;
|
||
|
expectation->min_calls_expected = 1;
|
||
|
expectation->max_calls_expected = 1;
|
||
|
|
||
|
EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test)));
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
static void mock_test_validate_clears_expectations(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
int_eq(trgt, 5),
|
||
|
int_eq(trgt, -4)
|
||
|
};
|
||
|
int param0 = 5, param1 = -4;
|
||
|
static const char * const two_param_types[] = {"int", "int"};
|
||
|
const void *two_params[] = {¶m0, ¶m1};
|
||
|
|
||
|
struct mock_expectation *expectation;
|
||
|
|
||
|
mock->type = MOCK_TYPE_STRICT;
|
||
|
|
||
|
/* If all goes well, the mock_test should not fail. */
|
||
|
expectation = Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test),
|
||
|
any(test))));
|
||
|
|
||
|
/* Add an arbitrary matcher for 0 calls */
|
||
|
expectation = mock_add_matcher(mock, "test_printk", test_printk,
|
||
|
matchers, ARRAY_SIZE(matchers));
|
||
|
expectation->times_called = 0;
|
||
|
expectation->min_calls_expected = 0;
|
||
|
expectation->max_calls_expected = 0;
|
||
|
|
||
|
/* Should have 0 calls and should clear the previous expectation */
|
||
|
mock_validate_expectations(mock);
|
||
|
|
||
|
/* Add a new matcher for 1 call */
|
||
|
expectation = mock_add_matcher(mock, "test_printk", test_printk,
|
||
|
matchers, ARRAY_SIZE(matchers));
|
||
|
expectation->times_called = 0;
|
||
|
expectation->min_calls_expected = 1;
|
||
|
expectation->max_calls_expected = 1;
|
||
|
|
||
|
/* Satisfy previous matcher */
|
||
|
mock->do_expect(mock, "test_printk", test_printk, two_param_types,
|
||
|
two_params, ARRAY_SIZE(two_params));
|
||
|
|
||
|
/*
|
||
|
* Validate previous satisfy; if we didn't clear the previous
|
||
|
* expectation, it would fail the mock_test.
|
||
|
*/
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void mock_stub(int a) { }
|
||
|
|
||
|
/* Common references for InSequence tests */
|
||
|
static int param_len = 1;
|
||
|
static const char * const param_type[] = {"int"};
|
||
|
|
||
|
static const void *a_params[] = { &(int){1} };
|
||
|
static const void *b_params[] = { &(int){2} };
|
||
|
static const void *c_params[] = { &(int){3} };
|
||
|
|
||
|
/* Simple test of InSequence, a -> b -> c */
|
||
|
static void mock_test_in_sequence_simple_pass(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
struct mock_param_matcher *c_matchers[] = { int_eq(trgt, 3) };
|
||
|
|
||
|
struct mock_expectation *c = mock_add_matcher(mock, "c", mock_stub,
|
||
|
c_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
struct mock_expectation *a = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
|
||
|
InSequence(test, a, b, c);
|
||
|
|
||
|
Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test))));
|
||
|
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "c", mock_stub, param_type, c_params, param_len);
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
static void mock_test_in_sequence_simple_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
struct mock_param_matcher *c_matchers[] = { int_eq(trgt, 3) };
|
||
|
|
||
|
struct mock_expectation *c = mock_add_matcher(mock, "c", mock_stub,
|
||
|
c_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
struct mock_expectation *a = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
|
||
|
InSequence(test, a, b, c);
|
||
|
|
||
|
EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test)));
|
||
|
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "c", mock_stub, param_type, c_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
}
|
||
|
|
||
|
/* More complex test of InSequence on two chains in v formation:
|
||
|
* a -> c
|
||
|
* b -> c
|
||
|
*/
|
||
|
static void mock_test_in_sequence_abc_success(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
struct mock_param_matcher *c_matchers[] = { int_eq(trgt, 3) };
|
||
|
|
||
|
struct mock_expectation *c = mock_add_matcher(mock, "c", mock_stub,
|
||
|
c_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
struct mock_expectation *a = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
|
||
|
InSequence(test, a, c);
|
||
|
InSequence(test, b, c);
|
||
|
|
||
|
Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test))));
|
||
|
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "c", mock_stub, param_type, c_params, param_len);
|
||
|
}
|
||
|
|
||
|
static void mock_test_in_sequence_bac_success(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
struct mock_param_matcher *c_matchers[] = { int_eq(trgt, 3) };
|
||
|
|
||
|
struct mock_expectation *c = mock_add_matcher(mock, "c", mock_stub,
|
||
|
c_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
struct mock_expectation *a = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
|
||
|
InSequence(test, a, c);
|
||
|
InSequence(test, b, c);
|
||
|
|
||
|
Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test))));
|
||
|
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "c", mock_stub, param_type, c_params, param_len);
|
||
|
}
|
||
|
|
||
|
static void mock_test_in_sequence_no_a_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
struct mock_param_matcher *c_matchers[] = { int_eq(trgt, 3) };
|
||
|
|
||
|
struct mock_expectation *c = mock_add_matcher(mock, "c", mock_stub,
|
||
|
c_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
struct mock_expectation *a = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
|
||
|
InSequence(test, a, c);
|
||
|
InSequence(test, b, c);
|
||
|
|
||
|
EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test)));
|
||
|
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "c", mock_stub, param_type, c_params, param_len);
|
||
|
}
|
||
|
|
||
|
static void mock_test_in_sequence_retire_on_saturation(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
struct mock_param_matcher *c_matchers[] = { int_eq(trgt, 3) };
|
||
|
|
||
|
struct mock_expectation *c = mock_add_matcher(mock, "c", mock_stub,
|
||
|
c_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
struct mock_expectation *a_1 = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
struct mock_expectation *a_2 = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
|
||
|
InSequence(test, a_1, b, a_2, c);
|
||
|
|
||
|
Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test))));
|
||
|
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "c", mock_stub, param_type, c_params, param_len);
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
static void mock_test_atleast(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
|
||
|
struct mock_expectation *a = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
|
||
|
AtLeast(2, a);
|
||
|
AtLeast(1, b);
|
||
|
Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test))));
|
||
|
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
static void mock_test_atleast_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
|
||
|
AtLeast(2, b);
|
||
|
EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test)));
|
||
|
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
static void mock_test_atmost(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
struct mock_param_matcher *c_matchers[] = { int_eq(trgt, 3) };
|
||
|
|
||
|
struct mock_expectation *a = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
struct mock_expectation *c = mock_add_matcher(mock, "c", mock_stub,
|
||
|
c_matchers, param_len);
|
||
|
|
||
|
AtMost(2, a);
|
||
|
AtMost(1, b);
|
||
|
AtMost(2, c);
|
||
|
Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test))));
|
||
|
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "c", mock_stub, param_type, c_params, param_len);
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
static void mock_test_atmost_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
|
||
|
AtMost(2, b);
|
||
|
EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test)));
|
||
|
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
static void mock_test_between(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
|
||
|
Between(2, 4, b);
|
||
|
Never(EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test))));
|
||
|
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
static void mock_test_between_fail(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
|
||
|
struct mock_param_matcher *a_matchers[] = { int_eq(trgt, 1) };
|
||
|
struct mock_param_matcher *b_matchers[] = { int_eq(trgt, 2) };
|
||
|
|
||
|
struct mock_expectation *a = mock_add_matcher(mock, "a", mock_stub,
|
||
|
a_matchers, param_len);
|
||
|
struct mock_expectation *b = mock_add_matcher(mock, "b", mock_stub,
|
||
|
b_matchers, param_len);
|
||
|
|
||
|
Between(2, 3, a);
|
||
|
Between(1, 2, b);
|
||
|
Times(2, EXPECT_CALL(fail(mock_get_ctrl(mock_test), any(test))));
|
||
|
|
||
|
mock->do_expect(mock, "a", mock_stub, param_type, a_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
mock->do_expect(mock, "b", mock_stub, param_type, b_params, param_len);
|
||
|
|
||
|
mock_validate_expectations(mock);
|
||
|
}
|
||
|
|
||
|
void *do_mocked_fail(struct mock_action *this, const void **params, int len)
|
||
|
{
|
||
|
static const int ret;
|
||
|
struct test_stream * const *stream_ptr = params[0];
|
||
|
struct test_stream *stream = *stream_ptr;
|
||
|
|
||
|
stream->set_level(stream, KERN_ERR);
|
||
|
stream->commit(stream);
|
||
|
return (void *) &ret;
|
||
|
}
|
||
|
|
||
|
static struct mock_action mocked_fail = {
|
||
|
.do_action = do_mocked_fail
|
||
|
};
|
||
|
|
||
|
static int mock_test_init(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx;
|
||
|
|
||
|
ctx = test_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
|
||
|
if (!ctx)
|
||
|
return -ENOMEM;
|
||
|
test->priv = ctx;
|
||
|
|
||
|
ctx->mock_test = CONSTRUCT_MOCK(KUNIT_T, test);
|
||
|
if (!ctx->mock_test)
|
||
|
return -EINVAL;
|
||
|
|
||
|
ctx->mock = test_kzalloc(test, sizeof(*ctx->mock), GFP_KERNEL);
|
||
|
if (!ctx->mock)
|
||
|
return -ENOMEM;
|
||
|
mock_init_ctrl(mock_get_trgt(ctx->mock_test), ctx->mock);
|
||
|
|
||
|
/* This test suite tests the behaviour of the error messages printed
|
||
|
* when mocks fail, which requires the mocked fail to commit the
|
||
|
* stream.
|
||
|
*/
|
||
|
mock_set_default_action(mock_get_ctrl(ctx->mock_test),
|
||
|
"fail", fail, &mocked_fail);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void mock_test_and_matcher_accept(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
const int param0 = 5;
|
||
|
static const char * const param_types[] = {"int"};
|
||
|
const void *params[] = {¶m0};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
and(test, int_gt(test, 4), int_lt(test, 6))
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
param_types,
|
||
|
params,
|
||
|
ARRAY_SIZE(params));
|
||
|
ASSERT_NOT_ERR_OR_NULL(test, ret);
|
||
|
EXPECT_EQ(test, 1, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void mock_test_and_matcher_reject_left(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
const int param0 = 5;
|
||
|
static const char * const param_types[] = {"int"};
|
||
|
const void *params[] = {¶m0};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
and(test, int_gt(test, 5), int_lt(test, 6))
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
param_types,
|
||
|
params,
|
||
|
ARRAY_SIZE(params));
|
||
|
EXPECT_FALSE(test, ret);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
static void mock_test_and_matcher_reject_right(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
const int param0 = 5;
|
||
|
static const char * const param_types[] = {"int"};
|
||
|
const void *params[] = {¶m0};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
and(test, int_gt(test, 4), int_lt(test, 5))
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
param_types,
|
||
|
params,
|
||
|
ARRAY_SIZE(params));
|
||
|
EXPECT_FALSE(test, ret);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
static void mock_test_or_matcher_reject(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
const int param0 = 5;
|
||
|
static const char * const param_types[] = {"int"};
|
||
|
const void *params[] = {¶m0};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
or(test, int_lt(test, 4), int_gt(test, 6))
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
param_types,
|
||
|
params,
|
||
|
ARRAY_SIZE(params));
|
||
|
EXPECT_FALSE(test, ret);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void mock_test_or_matcher_accept_left(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
const int param0 = 5;
|
||
|
static const char * const param_types[] = {"int"};
|
||
|
const void *params[] = {¶m0};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
or(test, int_gt(test, 4), int_gt(test, 6))
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
param_types,
|
||
|
params,
|
||
|
ARRAY_SIZE(params));
|
||
|
ASSERT_NOT_ERR_OR_NULL(test, ret);
|
||
|
EXPECT_EQ(test, 1, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
static void mock_test_or_matcher_accept_right(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
const int param0 = 5;
|
||
|
static const char * const param_types[] = {"int"};
|
||
|
const void *params[] = {¶m0};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
or(test, int_lt(test, 4), int_lt(test, 6))
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
param_types,
|
||
|
params,
|
||
|
ARRAY_SIZE(params));
|
||
|
ASSERT_NOT_ERR_OR_NULL(test, ret);
|
||
|
EXPECT_EQ(test, 1, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
static void mock_test_not_matcher_reject(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
const int param0 = 5;
|
||
|
static const char * const param_types[] = {"int"};
|
||
|
const void *params[] = {¶m0};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
not(test, int_eq(test, 5))
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
param_types,
|
||
|
params,
|
||
|
ARRAY_SIZE(params));
|
||
|
EXPECT_FALSE(test, ret);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void mock_test_not_matcher_accept(struct KUNIT_T *test)
|
||
|
{
|
||
|
struct mock_test_context *ctx = test->priv;
|
||
|
struct MOCK(KUNIT_T) *mock_test = ctx->mock_test;
|
||
|
struct KUNIT_T *trgt = mock_get_trgt(mock_test);
|
||
|
struct mock *mock = ctx->mock;
|
||
|
const int param0 = 5;
|
||
|
static const char * const param_types[] = {"int"};
|
||
|
const void *params[] = {¶m0};
|
||
|
struct mock_param_matcher *matchers[] = {
|
||
|
not(test, int_eq(test, 100500))
|
||
|
};
|
||
|
struct mock_expectation *expectation;
|
||
|
const void *ret;
|
||
|
|
||
|
expectation = mock_add_matcher(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
matchers,
|
||
|
ARRAY_SIZE(matchers));
|
||
|
expectation->action = int_return(trgt, 0);
|
||
|
EXPECT_EQ(test, 0, expectation->times_called);
|
||
|
|
||
|
ret = mock->do_expect(mock,
|
||
|
"",
|
||
|
NULL,
|
||
|
param_types,
|
||
|
params,
|
||
|
ARRAY_SIZE(params));
|
||
|
ASSERT_NOT_ERR_OR_NULL(test, ret);
|
||
|
EXPECT_EQ(test, 1, expectation->times_called);
|
||
|
}
|
||
|
|
||
|
static struct KUNIT_CASE_T mock_test_cases[] = {
|
||
|
TEST_CASE(mock_test_do_expect_basic),
|
||
|
TEST_CASE(mock_test_ptr_eq),
|
||
|
TEST_CASE(mock_test_ptr_eq_not_equal),
|
||
|
TEST_CASE(mock_test_failed_expect_call_fails_test),
|
||
|
TEST_CASE(mock_test_do_expect_default_return),
|
||
|
TEST_CASE(mock_test_mock_validate_expectations),
|
||
|
TEST_CASE(mock_test_strict_no_expectations_will_fail),
|
||
|
TEST_CASE(mock_test_naggy_no_expectations_no_fail),
|
||
|
TEST_CASE(mock_test_nice_no_expectations_do_nothing),
|
||
|
TEST_CASE(mock_test_strict_no_matching_expectations_fail),
|
||
|
TEST_CASE(mock_test_naggy_no_matching_expectations_fail),
|
||
|
TEST_CASE(mock_test_nice_no_matching_expectations_fail),
|
||
|
TEST_CASE(mock_test_validate_clears_expectations),
|
||
|
TEST_CASE(mock_test_in_sequence_simple_pass),
|
||
|
TEST_CASE(mock_test_in_sequence_simple_fail),
|
||
|
TEST_CASE(mock_test_in_sequence_abc_success),
|
||
|
TEST_CASE(mock_test_in_sequence_bac_success),
|
||
|
TEST_CASE(mock_test_in_sequence_no_a_fail),
|
||
|
TEST_CASE(mock_test_in_sequence_retire_on_saturation),
|
||
|
TEST_CASE(mock_test_atleast),
|
||
|
TEST_CASE(mock_test_atleast_fail),
|
||
|
TEST_CASE(mock_test_atmost),
|
||
|
TEST_CASE(mock_test_atmost_fail),
|
||
|
TEST_CASE(mock_test_between),
|
||
|
TEST_CASE(mock_test_between_fail),
|
||
|
TEST_CASE(mock_test_and_matcher_accept),
|
||
|
TEST_CASE(mock_test_and_matcher_reject_left),
|
||
|
TEST_CASE(mock_test_and_matcher_reject_right),
|
||
|
TEST_CASE(mock_test_or_matcher_reject),
|
||
|
TEST_CASE(mock_test_or_matcher_accept_left),
|
||
|
TEST_CASE(mock_test_or_matcher_accept_right),
|
||
|
TEST_CASE(mock_test_not_matcher_reject),
|
||
|
TEST_CASE(mock_test_not_matcher_accept),
|
||
|
{},
|
||
|
};
|
||
|
|
||
|
static struct KUNIT_SUITE_T mock_test_module = {
|
||
|
.name = "mock-test",
|
||
|
.init = mock_test_init,
|
||
|
.test_cases = mock_test_cases,
|
||
|
};
|
||
|
|
||
|
module_test(mock_test_module);
|