All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brendan Higgins <brendanhiggins@google.com>
To: gregkh@linuxfoundation.org, keescook@google.com,
	mcgrof@kernel.org, shuah@kernel.org
Cc: joel@jms.id.au, mpe@ellerman.id.au, joe@perches.com,
	brakmo@fb.com, rostedt@goodmis.org, Tim.Bird@sony.com,
	khilman@baylibre.com, julia.lawall@lip6.fr,
	linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com,
	linux-kernel@vger.kernel.org, jdike@addtoit.com, richard@nod.at,
	linux-um@lists.infradead.org,
	Brendan Higgins <brendanhiggins@google.com>
Subject: [RFC v1 23/31] kunit: mock: add parameter capturers
Date: Tue, 16 Oct 2018 16:51:12 -0700	[thread overview]
Message-ID: <20181016235120.138227-24-brendanhiggins@google.com> (raw)
In-Reply-To: <20181016235120.138227-1-brendanhiggins@google.com>

Adds the concept of an argument capturer which, when used with a matcher
in an EXPECT_CALL(...), will capture the value of the matching argument.

Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
---
 include/kunit/mock.h | 83 ++++++++++++++++++++++++++++++++++++++++++++
 kunit/common-mocks.c | 78 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+)

diff --git a/include/kunit/mock.h b/include/kunit/mock.h
index c3615e80d96ee..0e1aa568709a1 100644
--- a/include/kunit/mock.h
+++ b/include/kunit/mock.h
@@ -1172,6 +1172,89 @@ struct mock_param_matcher *test_struct_cmp(
 		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));
+ *		TEST_EXPECT_CALL(add(any(test), capturer_to_matcher(capturer)));
+ *		TEST_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)
+
+/**
+ * TEST_ASSERT_PARAM_CAPTURED(): Asserts that a parameter has been captured.
+ * @test: the associated test
+ * @capturer: the param capturer
+ *
+ * See &struct mock_param_capturer for an example.
+ */
+#define TEST_ASSERT_PARAM_CAPTURED(test, capturer)			       \
+		TEST_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[],
diff --git a/kunit/common-mocks.c b/kunit/common-mocks.c
index ce0159923814d..62528b7df83c6 100644
--- a/kunit/common-mocks.c
+++ b/kunit/common-mocks.c
@@ -323,6 +323,84 @@ struct mock_param_matcher *test_struct_cmp(
 	return &matcher->matcher;
 }
 
+static bool match_and_capture_param(struct mock_param_matcher *pmatcher,
+				    struct test_stream *stream,
+				    const void *param)
+{
+	struct mock_param_capturer *capturer =
+			container_of(pmatcher,
+				     struct mock_param_capturer,
+				     matcher);
+	struct mock_param_matcher *child_matcher = capturer->child_matcher;
+	bool matches;
+
+	matches = child_matcher->match(child_matcher, stream, param);
+	if (matches)
+		capturer->captured_param = capturer->capture_param(stream->test,
+								   param);
+
+	return matches;
+}
+
+struct mock_param_capturer *mock_param_capturer_create(
+		struct test *test,
+		struct mock_param_matcher *child_matcher,
+		void *(*capture_param)(struct test *, const void *))
+{
+	struct mock_param_capturer *capturer;
+
+	capturer = test_kzalloc(test, sizeof(*capturer), GFP_KERNEL);
+	if (!capturer)
+		return NULL;
+
+	capturer->matcher.match = match_and_capture_param;
+	capturer->child_matcher = child_matcher;
+	capturer->capture_param = capture_param;
+	capturer->captured_param = NULL;
+
+	return capturer;
+}
+
+static void *mock_capture_int(struct test *test, const void *param)
+{
+	int value = CONVERT_TO_ACTUAL_TYPE(int, param);
+	int *pvalue;
+
+	pvalue = test_kzalloc(test, sizeof(*pvalue), GFP_KERNEL);
+	if (!pvalue)
+		return NULL;
+	*pvalue = value;
+
+	return pvalue;
+}
+
+struct mock_param_capturer *mock_int_capturer_create(
+		struct test *test, struct mock_param_matcher *child_matcher)
+{
+	return mock_param_capturer_create(test,
+					  child_matcher,
+					  mock_capture_int);
+}
+
+static void *mock_capture_ptr(struct test *test, const void *param)
+{
+	void *ptr = CONVERT_TO_ACTUAL_TYPE(void *, param);
+	void **pptr;
+
+	pptr = test_kzalloc(test, sizeof(*pptr), GFP_KERNEL);
+	*pptr = ptr;
+
+	return pptr;
+}
+
+struct mock_param_capturer *mock_ptr_capturer_create(
+		struct test *test, struct mock_param_matcher *child_matcher)
+{
+	return mock_param_capturer_create(test,
+					  child_matcher,
+					  mock_capture_ptr);
+}
+
 #define DEFINE_RETURN_ACTION_STRUCT(type_name, type)			       \
 		struct mock_##type_name##_action {			       \
 			struct mock_action action;			       \
-- 
2.19.1.331.ge82ca0e54c-goog


WARNING: multiple messages have this Message-ID (diff)
From: brendanhiggins at google.com (Brendan Higgins)
Subject: [RFC v1 23/31] kunit: mock: add parameter capturers
Date: Tue, 16 Oct 2018 16:51:12 -0700	[thread overview]
Message-ID: <20181016235120.138227-24-brendanhiggins@google.com> (raw)
In-Reply-To: <20181016235120.138227-1-brendanhiggins@google.com>

Adds the concept of an argument capturer which, when used with a matcher
in an EXPECT_CALL(...), will capture the value of the matching argument.

Signed-off-by: Brendan Higgins <brendanhiggins at google.com>
---
 include/kunit/mock.h | 83 ++++++++++++++++++++++++++++++++++++++++++++
 kunit/common-mocks.c | 78 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+)

diff --git a/include/kunit/mock.h b/include/kunit/mock.h
index c3615e80d96ee..0e1aa568709a1 100644
--- a/include/kunit/mock.h
+++ b/include/kunit/mock.h
@@ -1172,6 +1172,89 @@ struct mock_param_matcher *test_struct_cmp(
 		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));
+ *		TEST_EXPECT_CALL(add(any(test), capturer_to_matcher(capturer)));
+ *		TEST_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)
+
+/**
+ * TEST_ASSERT_PARAM_CAPTURED(): Asserts that a parameter has been captured.
+ * @test: the associated test
+ * @capturer: the param capturer
+ *
+ * See &struct mock_param_capturer for an example.
+ */
+#define TEST_ASSERT_PARAM_CAPTURED(test, capturer)			       \
+		TEST_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[],
diff --git a/kunit/common-mocks.c b/kunit/common-mocks.c
index ce0159923814d..62528b7df83c6 100644
--- a/kunit/common-mocks.c
+++ b/kunit/common-mocks.c
@@ -323,6 +323,84 @@ struct mock_param_matcher *test_struct_cmp(
 	return &matcher->matcher;
 }
 
+static bool match_and_capture_param(struct mock_param_matcher *pmatcher,
+				    struct test_stream *stream,
+				    const void *param)
+{
+	struct mock_param_capturer *capturer =
+			container_of(pmatcher,
+				     struct mock_param_capturer,
+				     matcher);
+	struct mock_param_matcher *child_matcher = capturer->child_matcher;
+	bool matches;
+
+	matches = child_matcher->match(child_matcher, stream, param);
+	if (matches)
+		capturer->captured_param = capturer->capture_param(stream->test,
+								   param);
+
+	return matches;
+}
+
+struct mock_param_capturer *mock_param_capturer_create(
+		struct test *test,
+		struct mock_param_matcher *child_matcher,
+		void *(*capture_param)(struct test *, const void *))
+{
+	struct mock_param_capturer *capturer;
+
+	capturer = test_kzalloc(test, sizeof(*capturer), GFP_KERNEL);
+	if (!capturer)
+		return NULL;
+
+	capturer->matcher.match = match_and_capture_param;
+	capturer->child_matcher = child_matcher;
+	capturer->capture_param = capture_param;
+	capturer->captured_param = NULL;
+
+	return capturer;
+}
+
+static void *mock_capture_int(struct test *test, const void *param)
+{
+	int value = CONVERT_TO_ACTUAL_TYPE(int, param);
+	int *pvalue;
+
+	pvalue = test_kzalloc(test, sizeof(*pvalue), GFP_KERNEL);
+	if (!pvalue)
+		return NULL;
+	*pvalue = value;
+
+	return pvalue;
+}
+
+struct mock_param_capturer *mock_int_capturer_create(
+		struct test *test, struct mock_param_matcher *child_matcher)
+{
+	return mock_param_capturer_create(test,
+					  child_matcher,
+					  mock_capture_int);
+}
+
+static void *mock_capture_ptr(struct test *test, const void *param)
+{
+	void *ptr = CONVERT_TO_ACTUAL_TYPE(void *, param);
+	void **pptr;
+
+	pptr = test_kzalloc(test, sizeof(*pptr), GFP_KERNEL);
+	*pptr = ptr;
+
+	return pptr;
+}
+
+struct mock_param_capturer *mock_ptr_capturer_create(
+		struct test *test, struct mock_param_matcher *child_matcher)
+{
+	return mock_param_capturer_create(test,
+					  child_matcher,
+					  mock_capture_ptr);
+}
+
 #define DEFINE_RETURN_ACTION_STRUCT(type_name, type)			       \
 		struct mock_##type_name##_action {			       \
 			struct mock_action action;			       \
-- 
2.19.1.331.ge82ca0e54c-goog

WARNING: multiple messages have this Message-ID (diff)
From: brendanhiggins@google.com (Brendan Higgins)
Subject: [RFC v1 23/31] kunit: mock: add parameter capturers
Date: Tue, 16 Oct 2018 16:51:12 -0700	[thread overview]
Message-ID: <20181016235120.138227-24-brendanhiggins@google.com> (raw)
Message-ID: <20181016235112.2rlqyUzW4bQBh-kHgwsj2yJSj8j1nZ0f0tiD9LZe8b8@z> (raw)
In-Reply-To: <20181016235120.138227-1-brendanhiggins@google.com>

Adds the concept of an argument capturer which, when used with a matcher
in an EXPECT_CALL(...), will capture the value of the matching argument.

Signed-off-by: Brendan Higgins <brendanhiggins at google.com>
---
 include/kunit/mock.h | 83 ++++++++++++++++++++++++++++++++++++++++++++
 kunit/common-mocks.c | 78 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+)

diff --git a/include/kunit/mock.h b/include/kunit/mock.h
index c3615e80d96ee..0e1aa568709a1 100644
--- a/include/kunit/mock.h
+++ b/include/kunit/mock.h
@@ -1172,6 +1172,89 @@ struct mock_param_matcher *test_struct_cmp(
 		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));
+ *		TEST_EXPECT_CALL(add(any(test), capturer_to_matcher(capturer)));
+ *		TEST_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)
+
+/**
+ * TEST_ASSERT_PARAM_CAPTURED(): Asserts that a parameter has been captured.
+ * @test: the associated test
+ * @capturer: the param capturer
+ *
+ * See &struct mock_param_capturer for an example.
+ */
+#define TEST_ASSERT_PARAM_CAPTURED(test, capturer)			       \
+		TEST_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[],
diff --git a/kunit/common-mocks.c b/kunit/common-mocks.c
index ce0159923814d..62528b7df83c6 100644
--- a/kunit/common-mocks.c
+++ b/kunit/common-mocks.c
@@ -323,6 +323,84 @@ struct mock_param_matcher *test_struct_cmp(
 	return &matcher->matcher;
 }
 
+static bool match_and_capture_param(struct mock_param_matcher *pmatcher,
+				    struct test_stream *stream,
+				    const void *param)
+{
+	struct mock_param_capturer *capturer =
+			container_of(pmatcher,
+				     struct mock_param_capturer,
+				     matcher);
+	struct mock_param_matcher *child_matcher = capturer->child_matcher;
+	bool matches;
+
+	matches = child_matcher->match(child_matcher, stream, param);
+	if (matches)
+		capturer->captured_param = capturer->capture_param(stream->test,
+								   param);
+
+	return matches;
+}
+
+struct mock_param_capturer *mock_param_capturer_create(
+		struct test *test,
+		struct mock_param_matcher *child_matcher,
+		void *(*capture_param)(struct test *, const void *))
+{
+	struct mock_param_capturer *capturer;
+
+	capturer = test_kzalloc(test, sizeof(*capturer), GFP_KERNEL);
+	if (!capturer)
+		return NULL;
+
+	capturer->matcher.match = match_and_capture_param;
+	capturer->child_matcher = child_matcher;
+	capturer->capture_param = capture_param;
+	capturer->captured_param = NULL;
+
+	return capturer;
+}
+
+static void *mock_capture_int(struct test *test, const void *param)
+{
+	int value = CONVERT_TO_ACTUAL_TYPE(int, param);
+	int *pvalue;
+
+	pvalue = test_kzalloc(test, sizeof(*pvalue), GFP_KERNEL);
+	if (!pvalue)
+		return NULL;
+	*pvalue = value;
+
+	return pvalue;
+}
+
+struct mock_param_capturer *mock_int_capturer_create(
+		struct test *test, struct mock_param_matcher *child_matcher)
+{
+	return mock_param_capturer_create(test,
+					  child_matcher,
+					  mock_capture_int);
+}
+
+static void *mock_capture_ptr(struct test *test, const void *param)
+{
+	void *ptr = CONVERT_TO_ACTUAL_TYPE(void *, param);
+	void **pptr;
+
+	pptr = test_kzalloc(test, sizeof(*pptr), GFP_KERNEL);
+	*pptr = ptr;
+
+	return pptr;
+}
+
+struct mock_param_capturer *mock_ptr_capturer_create(
+		struct test *test, struct mock_param_matcher *child_matcher)
+{
+	return mock_param_capturer_create(test,
+					  child_matcher,
+					  mock_capture_ptr);
+}
+
 #define DEFINE_RETURN_ACTION_STRUCT(type_name, type)			       \
 		struct mock_##type_name##_action {			       \
 			struct mock_action action;			       \
-- 
2.19.1.331.ge82ca0e54c-goog

WARNING: multiple messages have this Message-ID (diff)
From: Brendan Higgins <brendanhiggins@google.com>
To: gregkh@linuxfoundation.org, keescook@google.com,
	mcgrof@kernel.org, shuah@kernel.org
Cc: brakmo@fb.com, richard@nod.at, mpe@ellerman.id.au,
	Tim.Bird@sony.com, linux-um@lists.infradead.org,
	linux-kernel@vger.kernel.org, rostedt@goodmis.org,
	julia.lawall@lip6.fr, joel@jms.id.au,
	linux-kselftest@vger.kernel.org, khilman@baylibre.com,
	joe@perches.com, jdike@addtoit.com,
	Brendan Higgins <brendanhiggins@google.com>,
	kunit-dev@googlegroups.com
Subject: [RFC v1 23/31] kunit: mock: add parameter capturers
Date: Tue, 16 Oct 2018 16:51:12 -0700	[thread overview]
Message-ID: <20181016235120.138227-24-brendanhiggins@google.com> (raw)
In-Reply-To: <20181016235120.138227-1-brendanhiggins@google.com>

Adds the concept of an argument capturer which, when used with a matcher
in an EXPECT_CALL(...), will capture the value of the matching argument.

Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
---
 include/kunit/mock.h | 83 ++++++++++++++++++++++++++++++++++++++++++++
 kunit/common-mocks.c | 78 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+)

diff --git a/include/kunit/mock.h b/include/kunit/mock.h
index c3615e80d96ee..0e1aa568709a1 100644
--- a/include/kunit/mock.h
+++ b/include/kunit/mock.h
@@ -1172,6 +1172,89 @@ struct mock_param_matcher *test_struct_cmp(
 		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));
+ *		TEST_EXPECT_CALL(add(any(test), capturer_to_matcher(capturer)));
+ *		TEST_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)
+
+/**
+ * TEST_ASSERT_PARAM_CAPTURED(): Asserts that a parameter has been captured.
+ * @test: the associated test
+ * @capturer: the param capturer
+ *
+ * See &struct mock_param_capturer for an example.
+ */
+#define TEST_ASSERT_PARAM_CAPTURED(test, capturer)			       \
+		TEST_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[],
diff --git a/kunit/common-mocks.c b/kunit/common-mocks.c
index ce0159923814d..62528b7df83c6 100644
--- a/kunit/common-mocks.c
+++ b/kunit/common-mocks.c
@@ -323,6 +323,84 @@ struct mock_param_matcher *test_struct_cmp(
 	return &matcher->matcher;
 }
 
+static bool match_and_capture_param(struct mock_param_matcher *pmatcher,
+				    struct test_stream *stream,
+				    const void *param)
+{
+	struct mock_param_capturer *capturer =
+			container_of(pmatcher,
+				     struct mock_param_capturer,
+				     matcher);
+	struct mock_param_matcher *child_matcher = capturer->child_matcher;
+	bool matches;
+
+	matches = child_matcher->match(child_matcher, stream, param);
+	if (matches)
+		capturer->captured_param = capturer->capture_param(stream->test,
+								   param);
+
+	return matches;
+}
+
+struct mock_param_capturer *mock_param_capturer_create(
+		struct test *test,
+		struct mock_param_matcher *child_matcher,
+		void *(*capture_param)(struct test *, const void *))
+{
+	struct mock_param_capturer *capturer;
+
+	capturer = test_kzalloc(test, sizeof(*capturer), GFP_KERNEL);
+	if (!capturer)
+		return NULL;
+
+	capturer->matcher.match = match_and_capture_param;
+	capturer->child_matcher = child_matcher;
+	capturer->capture_param = capture_param;
+	capturer->captured_param = NULL;
+
+	return capturer;
+}
+
+static void *mock_capture_int(struct test *test, const void *param)
+{
+	int value = CONVERT_TO_ACTUAL_TYPE(int, param);
+	int *pvalue;
+
+	pvalue = test_kzalloc(test, sizeof(*pvalue), GFP_KERNEL);
+	if (!pvalue)
+		return NULL;
+	*pvalue = value;
+
+	return pvalue;
+}
+
+struct mock_param_capturer *mock_int_capturer_create(
+		struct test *test, struct mock_param_matcher *child_matcher)
+{
+	return mock_param_capturer_create(test,
+					  child_matcher,
+					  mock_capture_int);
+}
+
+static void *mock_capture_ptr(struct test *test, const void *param)
+{
+	void *ptr = CONVERT_TO_ACTUAL_TYPE(void *, param);
+	void **pptr;
+
+	pptr = test_kzalloc(test, sizeof(*pptr), GFP_KERNEL);
+	*pptr = ptr;
+
+	return pptr;
+}
+
+struct mock_param_capturer *mock_ptr_capturer_create(
+		struct test *test, struct mock_param_matcher *child_matcher)
+{
+	return mock_param_capturer_create(test,
+					  child_matcher,
+					  mock_capture_ptr);
+}
+
 #define DEFINE_RETURN_ACTION_STRUCT(type_name, type)			       \
 		struct mock_##type_name##_action {			       \
 			struct mock_action action;			       \
-- 
2.19.1.331.ge82ca0e54c-goog


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


  parent reply	other threads:[~2018-10-16 23:54 UTC|newest]

Thread overview: 210+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-16 23:50 [RFC v1 00/31] kunit: Introducing KUnit, the Linux kernel unit testing framework Brendan Higgins
2018-10-16 23:50 ` Brendan Higgins
2018-10-16 23:50 ` Brendan Higgins
2018-10-16 23:50 ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 01/31] kunit: test: added string_stream a std::stream like string builder Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 02/31] kunit: test: adds KUnit test runner core Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 03/31] kunit: test: added test resource management API Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 04/31] kunit: test: added test_stream a std::stream like logger Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 05/31] kunit: test: added the concept of expectations Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 06/31] arch: um: enabled running kunit from User Mode Linux Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-17 15:29   ` Kieran Bingham
2018-10-17 15:29     ` Kieran Bingham
2018-10-17 15:29     ` Kieran Bingham
2018-10-17 15:29     ` kieran.bingham
2018-10-17 17:43     ` Brendan Higgins
2018-10-17 17:43       ` Brendan Higgins
2018-10-17 17:43       ` Brendan Higgins
2018-10-17 17:43       ` brendanhiggins
2018-10-17 17:52     ` Tim.Bird
2018-10-17 17:52       ` Tim.Bird
2018-10-17 17:52       ` Tim.Bird
2018-10-17 17:52       ` Tim.Bird
2018-10-17 21:09       ` Brendan Higgins
2018-10-17 21:09         ` Brendan Higgins
2018-10-17 21:09         ` Brendan Higgins
2018-10-17 21:09         ` brendanhiggins
2018-10-17 21:18         ` Tim.Bird
2018-10-17 21:18           ` Tim.Bird
2018-10-17 21:18           ` Tim.Bird
2018-10-17 21:18           ` Tim.Bird
2018-10-17 22:45           ` Brendan Higgins
2018-10-17 22:45             ` Brendan Higgins
2018-10-17 22:45             ` Brendan Higgins
2018-10-17 22:45             ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 07/31] kunit: test: added initial tests Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 08/31] arch: um: added shim to trap to allow installing a fault catcher for tests Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 09/31] kunit: test: added the concept of assertions Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:50 ` [RFC v1 10/31] kunit: test: added concept of initcalls Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` Brendan Higgins
2018-10-16 23:50   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 11/31] kunit: test: added concept of post conditions Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 12/31] checkpatch: added support for struct MOCK(foo) syntax Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:59   ` Joe Perches
2018-10-16 23:59     ` Joe Perches
2018-10-16 23:59     ` Joe Perches
2018-10-16 23:59     ` joe
2018-10-17  0:03     ` Brendan Higgins
2018-10-17  0:03       ` Brendan Higgins
2018-10-17  0:03       ` Brendan Higgins
2018-10-17  0:03       ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 13/31] kunit: mock: added parameter list minipulation macros Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 14/31] kunit: mock: added internal mock infrastructure Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 15/31] kunit: mock: added basic matchers and actions Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 16/31] kunit: mock: added class mocking support Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 17/31] kunit: mock: added struct param matcher Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 18/31] kunit: mock: added parameter formatters Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 19/31] kunit: mock: implemented nice, strict and naggy mock distinctions Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 20/31] kunit: mock: add ability to mock functions with void context Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 21/31] kunit: mock: added support for arbitrary function mocking Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 22/31] kunit: mock: add the concept of spyable functions Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-17 22:46   ` Rob Herring
2018-10-17 22:46     ` Rob Herring
2018-10-17 22:46     ` Rob Herring
2018-10-17 22:46     ` rob.herring
2018-10-18  1:32     ` Brendan Higgins
2018-10-18  1:32       ` Brendan Higgins
2018-10-18  1:32       ` brendanhiggins
2018-10-16 23:51 ` Brendan Higgins [this message]
2018-10-16 23:51   ` [RFC v1 23/31] kunit: mock: add parameter capturers Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 24/31] kunit: improved sigsegv stack trace printing Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 25/31] kunit: added concept of platform mocking Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 26/31] arch: um: added stubs for mock iomem for KUnit Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-17 22:28   ` Rob Herring
2018-10-17 22:28     ` Rob Herring
2018-10-17 22:28     ` Rob Herring
2018-10-17 22:28     ` robh
2018-10-18  1:14     ` Brendan Higgins
2018-10-18  1:14       ` Brendan Higgins
2018-10-18  1:14       ` Brendan Higgins
2018-10-18  1:14       ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 27/31] Documentation: kunit: adds complete documentation " Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 28/31] kunit: added Python libraries for handing KUnit config and kernel Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 29/31] kunit: added KUnit wrapper script and simple output parser Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 30/31] kunit.py: improved output from python wrapper Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-16 23:51 ` [RFC v1 31/31] MAINTAINERS: add entry for KUnit the unit testing framework Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` Brendan Higgins
2018-10-16 23:51   ` brendanhiggins
2018-10-17  9:08 ` [RFC v1 00/31] kunit: Introducing KUnit, the Linux kernel " Daniel Vetter
2018-10-17  9:08   ` Daniel Vetter
2018-10-17  9:08   ` Daniel Vetter
2018-10-17  9:08   ` Daniel Vetter
2018-10-17  9:08   ` daniel
2018-10-17 17:49 ` Tim.Bird
2018-10-17 17:49   ` Tim.Bird
2018-10-17 17:49   ` Tim.Bird
2018-10-17 17:49   ` Tim.Bird
2018-10-17 22:22   ` Brendan Higgins
2018-10-17 22:22     ` Brendan Higgins
2018-10-17 22:22     ` Brendan Higgins
2018-10-17 22:22     ` brendanhiggins
2018-10-17 20:43 ` Rob Herring
2018-10-17 20:43   ` Rob Herring
2018-10-17 20:43   ` Rob Herring
2018-10-17 20:43   ` robh
2018-10-17 23:12 ` Randy Dunlap
2018-10-17 23:12   ` Randy Dunlap
2018-10-17 23:12   ` Randy Dunlap
2018-10-17 23:12   ` rdunlap
2018-10-18  2:05   ` Brendan Higgins
2018-10-18  2:05     ` Brendan Higgins
2018-10-18  2:05     ` Brendan Higgins
2018-10-18  2:05     ` brendanhiggins
2018-10-18  3:55 ` Dan Williams
2018-10-18  3:55   ` Dan Williams
2018-10-18  3:55   ` Dan Williams
2018-10-18  3:55   ` dan.j.williams
2018-10-18  3:55   ` Dan Williams
2018-10-19  6:27   ` Brendan Higgins
2018-10-19  6:27     ` Brendan Higgins
2018-10-19  6:27     ` Brendan Higgins
2018-10-19  6:27     ` brendanhiggins
2018-10-19  6:27     ` Brendan Higgins

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181016235120.138227-24-brendanhiggins@google.com \
    --to=brendanhiggins@google.com \
    --cc=Tim.Bird@sony.com \
    --cc=brakmo@fb.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jdike@addtoit.com \
    --cc=joe@perches.com \
    --cc=joel@jms.id.au \
    --cc=julia.lawall@lip6.fr \
    --cc=keescook@google.com \
    --cc=khilman@baylibre.com \
    --cc=kunit-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-um@lists.infradead.org \
    --cc=mcgrof@kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=richard@nod.at \
    --cc=rostedt@goodmis.org \
    --cc=shuah@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.