kunit: mock : Add three Cardinality expectation macro helpers.
- AtLeast : An expectation is called at least n times.
- AtMost : An expectation is called at most n times.
- Between : An expectation is called beween n to m(inclusive) times.
Change-Id: Ic1d96efce855495c8484512161a58df95cd93658
Signed-off-by: Harshal Tushar Lehri <halehri@google.com>
diff --git a/include/test/mock.h b/include/test/mock.h
index fd0dc4c..e599d21 100644
--- a/include/test/mock.h
+++ b/include/test/mock.h
@@ -292,6 +292,62 @@
}
/**
+ * 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
*
diff --git a/test/mock-test.c b/test/mock-test.c
index 7a6ce3b..48ac0ac 100644
--- a/test/mock-test.c
+++ b/test/mock-test.c
@@ -610,6 +610,154 @@
mock_validate_expectations(mock);
}
+static void mock_test_atleast(struct test *test)
+{
+ struct mock_test_context *ctx = test->priv;
+ struct MOCK(test) *mock_test = ctx->mock_test;
+ struct test *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 test *test)
+{
+ struct mock_test_context *ctx = test->priv;
+ struct MOCK(test) *mock_test = ctx->mock_test;
+ struct test *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 test *test)
+{
+ struct mock_test_context *ctx = test->priv;
+ struct MOCK(test) *mock_test = ctx->mock_test;
+ struct test *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 test *test)
+{
+ struct mock_test_context *ctx = test->priv;
+ struct MOCK(test) *mock_test = ctx->mock_test;
+ struct test *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 test *test)
+{
+ struct mock_test_context *ctx = test->priv;
+ struct MOCK(test) *mock_test = ctx->mock_test;
+ struct test *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 test *test)
+{
+ struct mock_test_context *ctx = test->priv;
+ struct MOCK(test) *mock_test = ctx->mock_test;
+ struct test *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;
@@ -672,7 +820,13 @@
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),
+ {},
};
static struct test_module mock_test_module = {