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 15/31] kunit: mock: added basic matchers and actions
Date: Tue, 16 Oct 2018 16:51:04 -0700	[thread overview]
Message-ID: <20181016235120.138227-16-brendanhiggins@google.com> (raw)
In-Reply-To: <20181016235120.138227-1-brendanhiggins@google.com>

Added basic matchers and actions needed for any kind of mocking to be
useful; these matchers and actions are how expectations for mocks are
described: what calls the mocks are expected to receive, and what the
mock should do under those circumstances.

Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
---
 include/kunit/mock.h | 222 +++++++++++++++++++++++++++++++++++
 kunit/Makefile       |   3 +-
 kunit/common-mocks.c | 272 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 496 insertions(+), 1 deletion(-)
 create mode 100644 kunit/common-mocks.c

diff --git a/include/kunit/mock.h b/include/kunit/mock.h
index 1a35c5702cb15..62e8afcaeab55 100644
--- a/include/kunit/mock.h
+++ b/include/kunit/mock.h
@@ -122,4 +122,226 @@ struct mock_expectation *mock_add_matcher(struct mock *mock,
 					  struct mock_param_matcher *matchers[],
 					  int len);
 
+#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 *test_int_eq(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_ne(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_lt(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_le(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_gt(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_ge(struct test *test, int expected);
+ *
+ * For a detailed list, please see
+ * ``include/linux/mock.h``.
+ */
+
+/* Matches any argument */
+struct mock_param_matcher *test_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 *test_u8_eq(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_ne(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_le(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_lt(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_ge(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_gt(struct test *test, u8 expected);
+
+struct mock_param_matcher *test_u16_eq(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_ne(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_le(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_lt(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_ge(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_gt(struct test *test, u16 expected);
+
+struct mock_param_matcher *test_u32_eq(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_ne(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_le(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_lt(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_ge(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_gt(struct test *test, u32 expected);
+
+struct mock_param_matcher *test_u64_eq(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_ne(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_le(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_lt(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_ge(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_gt(struct test *test, u64 expected);
+
+struct mock_param_matcher *test_char_eq(struct test *test, char expected);
+struct mock_param_matcher *test_char_ne(struct test *test, char expected);
+struct mock_param_matcher *test_char_le(struct test *test, char expected);
+struct mock_param_matcher *test_char_lt(struct test *test, char expected);
+struct mock_param_matcher *test_char_ge(struct test *test, char expected);
+struct mock_param_matcher *test_char_gt(struct test *test, char expected);
+
+struct mock_param_matcher *test_uchar_eq(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_ne(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_le(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_lt(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_ge(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_gt(struct test *test,
+					 unsigned char expected);
+
+struct mock_param_matcher *test_schar_eq(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_ne(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_le(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_lt(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_ge(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_gt(struct test *test,
+					 signed char expected);
+
+struct mock_param_matcher *test_short_eq(struct test *test, short expected);
+struct mock_param_matcher *test_short_ne(struct test *test, short expected);
+struct mock_param_matcher *test_short_le(struct test *test, short expected);
+struct mock_param_matcher *test_short_lt(struct test *test, short expected);
+struct mock_param_matcher *test_short_ge(struct test *test, short expected);
+struct mock_param_matcher *test_short_gt(struct test *test, short expected);
+
+struct mock_param_matcher *test_ushort_eq(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_ne(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_le(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_lt(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_ge(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_gt(struct test *test,
+					  unsigned short expected);
+
+struct mock_param_matcher *test_int_eq(struct test *test, int expected);
+struct mock_param_matcher *test_int_ne(struct test *test, int expected);
+struct mock_param_matcher *test_int_lt(struct test *test, int expected);
+struct mock_param_matcher *test_int_le(struct test *test, int expected);
+struct mock_param_matcher *test_int_gt(struct test *test, int expected);
+struct mock_param_matcher *test_int_ge(struct test *test, int expected);
+
+struct mock_param_matcher *test_uint_eq(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_ne(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_lt(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_le(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_gt(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_ge(struct test *test,
+					unsigned int expected);
+
+struct mock_param_matcher *test_long_eq(struct test *test, long expected);
+struct mock_param_matcher *test_long_ne(struct test *test, long expected);
+struct mock_param_matcher *test_long_le(struct test *test, long expected);
+struct mock_param_matcher *test_long_lt(struct test *test, long expected);
+struct mock_param_matcher *test_long_ge(struct test *test, long expected);
+struct mock_param_matcher *test_long_gt(struct test *test, long expected);
+
+struct mock_param_matcher *test_ulong_eq(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_ne(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_le(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_lt(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_ge(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_gt(struct test *test,
+					 unsigned long expected);
+
+struct mock_param_matcher *test_longlong_eq(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_ne(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_le(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_lt(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_ge(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_gt(struct test *test,
+					    long long expected);
+
+struct mock_param_matcher *test_ulonglong_eq(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_ne(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_le(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_lt(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_ge(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_gt(struct test *test,
+					     unsigned long long expected);
+
+/* Matches pointers. */
+struct mock_param_matcher *test_ptr_eq(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_ne(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_lt(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_le(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_gt(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_ge(struct test *test, void *expected);
+
+/* Matches memory sections and strings. */
+struct mock_param_matcher *test_memeq(struct test *test,
+				      const void *buf,
+				      size_t size);
+struct mock_param_matcher *test_streq(struct test *test, const char *str);
+
+struct mock_action *test_u8_return(struct test *test, u8 ret);
+struct mock_action *test_u16_return(struct test *test, u16 ret);
+struct mock_action *test_u32_return(struct test *test, u32 ret);
+struct mock_action *test_u64_return(struct test *test, u64 ret);
+struct mock_action *test_char_return(struct test *test, char ret);
+struct mock_action *test_uchar_return(struct test *test, unsigned char ret);
+struct mock_action *test_schar_return(struct test *test, signed char ret);
+struct mock_action *test_short_return(struct test *test, short ret);
+struct mock_action *test_ushort_return(struct test *test, unsigned short ret);
+struct mock_action *test_int_return(struct test *test, int ret);
+struct mock_action *test_uint_return(struct test *test, unsigned int ret);
+struct mock_action *test_long_return(struct test *test, long ret);
+struct mock_action *test_ulong_return(struct test *test, unsigned long ret);
+struct mock_action *test_longlong_return(struct test *test, long long ret);
+struct mock_action *test_ulonglong_return(struct test *test,
+					  unsigned long long ret);
+struct mock_action *test_ptr_return(struct test *test, void *ret);
+
 #endif /* _KUNIT_MOCK_H */
diff --git a/kunit/Makefile b/kunit/Makefile
index ad58110de695c..52a1da46cbd21 100644
--- a/kunit/Makefile
+++ b/kunit/Makefile
@@ -1,4 +1,5 @@
-obj-$(CONFIG_KUNIT)		+= test.o mock.o string-stream.o test-stream.o
+obj-$(CONFIG_KUNIT)		+= test.o mock.o common-mocks.o string-stream.o \
+  test-stream.o
 obj-$(CONFIG_KUNIT_TEST)		+= \
   test-test.o mock-macro-test.o string-stream-test.o
 obj-$(CONFIG_EXAMPLE_TEST)	+= example-test.o
diff --git a/kunit/common-mocks.c b/kunit/common-mocks.c
new file mode 100644
index 0000000000000..ecac9c1c29c0e
--- /dev/null
+++ b/kunit/common-mocks.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common KUnit mock call arg matchers and formatters.
+ *
+ * Copyright (C) 2018, Google LLC.
+ * Author: Brendan Higgins <brendanhiggins@google.com>
+ */
+
+#include <linux/kernel.h>
+#include <kunit/mock.h>
+
+static bool match_any(struct mock_param_matcher *pmatcher,
+		      struct test_stream *stream,
+		      const void *actual)
+{
+	stream->add(stream, "don't care");
+	return true;
+}
+
+static struct mock_param_matcher any_matcher = {
+	.match = match_any,
+};
+
+struct mock_param_matcher *test_any(struct test *test)
+{
+	return &any_matcher;
+}
+
+#define DEFINE_MATCHER_STRUCT(type_name, type)				       \
+		struct mock_##type_name##_matcher {			       \
+			struct mock_param_matcher matcher;		       \
+			type expected;					       \
+		};
+
+#define DEFINE_TO_MATCHER_STRUCT(type_name)				       \
+		struct mock_##type_name##_matcher *			       \
+		to_mock_##type_name##_matcher(				       \
+				struct mock_param_matcher *matcher)	       \
+		{							       \
+			return container_of(matcher,			       \
+					    struct mock_##type_name##_matcher, \
+					    matcher);			       \
+		}
+
+#define DEFINE_MATCH_FUNC(type_name, type, op_name, op)			       \
+		bool match_##type_name##_##op_name(			       \
+				struct mock_param_matcher *pmatcher,	       \
+				struct test_stream *stream,		       \
+				const void *pactual)			       \
+		{							       \
+			struct mock_##type_name##_matcher *matcher =	       \
+				to_mock_##type_name##_matcher(pmatcher);       \
+			type actual = *((type *) pactual);		       \
+			bool matches = actual op matcher->expected;	       \
+									       \
+			if (matches)					       \
+				stream->add(stream,			       \
+					    "%d "#op" %d",		       \
+					    actual,			       \
+					    matcher->expected);		       \
+			else						       \
+				stream->add(stream,			       \
+					    "%d not "#op" %d",		       \
+					    actual,			       \
+					    matcher->expected);		       \
+									       \
+			return matches;					       \
+		}
+
+#define DEFINE_MATCH_FACTORY(type_name, type, op_name)			       \
+		struct mock_param_matcher *test_##type_name##_##op_name(       \
+				struct test *test, type expected)	       \
+		{							       \
+			struct mock_##type_name##_matcher *matcher;	       \
+									       \
+			matcher = test_kmalloc(test,			       \
+					       sizeof(*matcher),	       \
+					       GFP_KERNEL);		       \
+			if (!matcher)					       \
+				return NULL;				       \
+									       \
+			matcher->matcher.match = match_##type_name##_##op_name;\
+			matcher->expected = expected;			       \
+			return &matcher->matcher;			       \
+		}
+
+#define DEFINE_MATCHER_WITH_TYPENAME(type_name, type)			       \
+		DEFINE_MATCHER_STRUCT(type_name, type)			       \
+		DEFINE_TO_MATCHER_STRUCT(type_name)			       \
+		DEFINE_MATCH_FUNC(type_name, type, eq, ==)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, eq)		       \
+		DEFINE_MATCH_FUNC(type_name, type, ne, !=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, ne)		       \
+		DEFINE_MATCH_FUNC(type_name, type, le, <=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, le)		       \
+		DEFINE_MATCH_FUNC(type_name, type, lt, <)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, lt)		       \
+		DEFINE_MATCH_FUNC(type_name, type, ge, >=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, ge)		       \
+		DEFINE_MATCH_FUNC(type_name, type, gt, >)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, gt)
+
+#define DEFINE_MATCHER(type) DEFINE_MATCHER_WITH_TYPENAME(type, type)
+
+DEFINE_MATCHER(u8);
+DEFINE_MATCHER(u16);
+DEFINE_MATCHER(u32);
+DEFINE_MATCHER(u64);
+DEFINE_MATCHER(char);
+DEFINE_MATCHER_WITH_TYPENAME(uchar, unsigned char);
+DEFINE_MATCHER_WITH_TYPENAME(schar, signed char);
+DEFINE_MATCHER(short);
+DEFINE_MATCHER_WITH_TYPENAME(ushort, unsigned short);
+DEFINE_MATCHER(int);
+DEFINE_MATCHER_WITH_TYPENAME(uint, unsigned int);
+DEFINE_MATCHER(long);
+DEFINE_MATCHER_WITH_TYPENAME(ulong, unsigned long);
+DEFINE_MATCHER_WITH_TYPENAME(longlong, long long);
+DEFINE_MATCHER_WITH_TYPENAME(ulonglong, unsigned long long);
+
+DEFINE_MATCHER_WITH_TYPENAME(ptr, void *);
+
+struct mock_memeq_matcher {
+	struct mock_param_matcher matcher;
+	const void *expected;
+	size_t size;
+};
+
+static bool match_memeq(struct mock_param_matcher *pmatcher,
+			struct test_stream *stream,
+			const void *pactual)
+{
+	struct mock_memeq_matcher *matcher =
+			container_of(pmatcher,
+				     struct mock_memeq_matcher,
+				     matcher);
+	const void *actual = CONVERT_TO_ACTUAL_TYPE(const void *, pactual);
+	bool matches = !memcmp(actual, matcher->expected, matcher->size);
+	int i;
+
+	for (i = 0; i < matcher->size; i++)
+		stream->add(stream, "%02x, ", ((const char *) actual)[i]);
+	if (matches)
+		stream->add(stream, "== ");
+	else
+		stream->add(stream, "!= ");
+	for (i = 0; i < matcher->size; i++)
+		stream->add(stream,
+			    "%02x, ",
+			    ((const char *) matcher->expected)[i]);
+
+	return matches;
+}
+
+struct mock_param_matcher *test_memeq(struct test *test,
+				      const void *buf,
+				      size_t size)
+{
+	struct mock_memeq_matcher *matcher;
+
+	matcher = test_kzalloc(test, sizeof(*matcher), GFP_KERNEL);
+	if (!matcher)
+		return NULL;
+
+	matcher->matcher.match = match_memeq;
+	matcher->expected = buf;
+	matcher->size = size;
+
+	return &matcher->matcher;
+}
+
+struct mock_streq_matcher {
+	struct mock_param_matcher matcher;
+	const char *expected;
+};
+
+static bool match_streq(struct mock_param_matcher *pmatcher,
+			struct test_stream *stream,
+			const void *pactual)
+{
+	struct mock_streq_matcher *matcher =
+			container_of(pmatcher,
+				     struct mock_streq_matcher,
+				     matcher);
+	const char *actual = CONVERT_TO_ACTUAL_TYPE(const char *, pactual);
+	bool matches = !strcmp(actual, matcher->expected);
+
+	if (matches)
+		stream->add(stream, "%s == %s", actual, matcher->expected);
+	else
+		stream->add(stream, "%s != %s", actual, matcher->expected);
+
+	return matches;
+}
+
+struct mock_param_matcher *test_streq(struct test *test, const char *str)
+{
+	struct mock_streq_matcher *matcher;
+
+	matcher = test_kzalloc(test, sizeof(*matcher), GFP_KERNEL);
+	if (!matcher)
+		return NULL;
+
+	matcher->matcher.match = match_streq;
+	matcher->expected = str;
+
+	return &matcher->matcher;
+}
+
+#define DEFINE_RETURN_ACTION_STRUCT(type_name, type)			       \
+		struct mock_##type_name##_action {			       \
+			struct mock_action action;			       \
+			type ret;					       \
+		};
+
+#define DEFINE_RETURN_ACTION_FUNC(type_name, type)			       \
+		void *do_##type_name##_return(struct mock_action *paction,     \
+					      const void **params,	       \
+					      int len)			       \
+		{							       \
+			struct mock_##type_name##_action *action =	       \
+					container_of(paction,		       \
+						     struct mock_##type_name##_action,\
+						     action);		       \
+									       \
+			return (void *) &action->ret;			       \
+		}
+
+#define DEFINE_RETURN_ACTION_FACTORY(type_name, type)			       \
+		struct mock_action *test_##type_name##_return(		       \
+				struct test *test,			       \
+				type ret)				       \
+		{							       \
+			struct mock_##type_name##_action *action;	       \
+									       \
+			action = test_kmalloc(test,			       \
+					      sizeof(*action),		       \
+					      GFP_KERNEL);		       \
+			if (!action)					       \
+				return NULL;				       \
+									       \
+			action->action.do_action = do_##type_name##_return;    \
+			action->ret = ret;				       \
+									       \
+			return &action->action;				       \
+		}
+
+#define DEFINE_RETURN_ACTION_WITH_TYPENAME(type_name, type)		       \
+		DEFINE_RETURN_ACTION_STRUCT(type_name, type);		       \
+		DEFINE_RETURN_ACTION_FUNC(type_name, type);		       \
+		DEFINE_RETURN_ACTION_FACTORY(type_name, type);
+
+#define DEFINE_RETURN_ACTION(type) \
+		DEFINE_RETURN_ACTION_WITH_TYPENAME(type, type)
+
+DEFINE_RETURN_ACTION(u8);
+DEFINE_RETURN_ACTION(u16);
+DEFINE_RETURN_ACTION(u32);
+DEFINE_RETURN_ACTION(u64);
+DEFINE_RETURN_ACTION(char);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(uchar, unsigned char);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(schar, signed char);
+DEFINE_RETURN_ACTION(short);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ushort, unsigned short);
+DEFINE_RETURN_ACTION(int);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(uint, unsigned int);
+DEFINE_RETURN_ACTION(long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ulong, unsigned long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(longlong, long long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ulonglong, unsigned long long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ptr, void *);
+
-- 
2.19.1.331.ge82ca0e54c-goog


WARNING: multiple messages have this Message-ID (diff)
From: brendanhiggins at google.com (Brendan Higgins)
Subject: [RFC v1 15/31] kunit: mock: added basic matchers and actions
Date: Tue, 16 Oct 2018 16:51:04 -0700	[thread overview]
Message-ID: <20181016235120.138227-16-brendanhiggins@google.com> (raw)
In-Reply-To: <20181016235120.138227-1-brendanhiggins@google.com>

Added basic matchers and actions needed for any kind of mocking to be
useful; these matchers and actions are how expectations for mocks are
described: what calls the mocks are expected to receive, and what the
mock should do under those circumstances.

Signed-off-by: Brendan Higgins <brendanhiggins at google.com>
---
 include/kunit/mock.h | 222 +++++++++++++++++++++++++++++++++++
 kunit/Makefile       |   3 +-
 kunit/common-mocks.c | 272 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 496 insertions(+), 1 deletion(-)
 create mode 100644 kunit/common-mocks.c

diff --git a/include/kunit/mock.h b/include/kunit/mock.h
index 1a35c5702cb15..62e8afcaeab55 100644
--- a/include/kunit/mock.h
+++ b/include/kunit/mock.h
@@ -122,4 +122,226 @@ struct mock_expectation *mock_add_matcher(struct mock *mock,
 					  struct mock_param_matcher *matchers[],
 					  int len);
 
+#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 *test_int_eq(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_ne(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_lt(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_le(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_gt(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_ge(struct test *test, int expected);
+ *
+ * For a detailed list, please see
+ * ``include/linux/mock.h``.
+ */
+
+/* Matches any argument */
+struct mock_param_matcher *test_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 *test_u8_eq(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_ne(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_le(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_lt(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_ge(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_gt(struct test *test, u8 expected);
+
+struct mock_param_matcher *test_u16_eq(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_ne(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_le(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_lt(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_ge(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_gt(struct test *test, u16 expected);
+
+struct mock_param_matcher *test_u32_eq(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_ne(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_le(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_lt(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_ge(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_gt(struct test *test, u32 expected);
+
+struct mock_param_matcher *test_u64_eq(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_ne(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_le(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_lt(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_ge(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_gt(struct test *test, u64 expected);
+
+struct mock_param_matcher *test_char_eq(struct test *test, char expected);
+struct mock_param_matcher *test_char_ne(struct test *test, char expected);
+struct mock_param_matcher *test_char_le(struct test *test, char expected);
+struct mock_param_matcher *test_char_lt(struct test *test, char expected);
+struct mock_param_matcher *test_char_ge(struct test *test, char expected);
+struct mock_param_matcher *test_char_gt(struct test *test, char expected);
+
+struct mock_param_matcher *test_uchar_eq(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_ne(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_le(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_lt(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_ge(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_gt(struct test *test,
+					 unsigned char expected);
+
+struct mock_param_matcher *test_schar_eq(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_ne(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_le(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_lt(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_ge(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_gt(struct test *test,
+					 signed char expected);
+
+struct mock_param_matcher *test_short_eq(struct test *test, short expected);
+struct mock_param_matcher *test_short_ne(struct test *test, short expected);
+struct mock_param_matcher *test_short_le(struct test *test, short expected);
+struct mock_param_matcher *test_short_lt(struct test *test, short expected);
+struct mock_param_matcher *test_short_ge(struct test *test, short expected);
+struct mock_param_matcher *test_short_gt(struct test *test, short expected);
+
+struct mock_param_matcher *test_ushort_eq(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_ne(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_le(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_lt(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_ge(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_gt(struct test *test,
+					  unsigned short expected);
+
+struct mock_param_matcher *test_int_eq(struct test *test, int expected);
+struct mock_param_matcher *test_int_ne(struct test *test, int expected);
+struct mock_param_matcher *test_int_lt(struct test *test, int expected);
+struct mock_param_matcher *test_int_le(struct test *test, int expected);
+struct mock_param_matcher *test_int_gt(struct test *test, int expected);
+struct mock_param_matcher *test_int_ge(struct test *test, int expected);
+
+struct mock_param_matcher *test_uint_eq(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_ne(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_lt(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_le(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_gt(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_ge(struct test *test,
+					unsigned int expected);
+
+struct mock_param_matcher *test_long_eq(struct test *test, long expected);
+struct mock_param_matcher *test_long_ne(struct test *test, long expected);
+struct mock_param_matcher *test_long_le(struct test *test, long expected);
+struct mock_param_matcher *test_long_lt(struct test *test, long expected);
+struct mock_param_matcher *test_long_ge(struct test *test, long expected);
+struct mock_param_matcher *test_long_gt(struct test *test, long expected);
+
+struct mock_param_matcher *test_ulong_eq(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_ne(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_le(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_lt(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_ge(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_gt(struct test *test,
+					 unsigned long expected);
+
+struct mock_param_matcher *test_longlong_eq(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_ne(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_le(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_lt(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_ge(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_gt(struct test *test,
+					    long long expected);
+
+struct mock_param_matcher *test_ulonglong_eq(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_ne(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_le(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_lt(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_ge(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_gt(struct test *test,
+					     unsigned long long expected);
+
+/* Matches pointers. */
+struct mock_param_matcher *test_ptr_eq(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_ne(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_lt(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_le(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_gt(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_ge(struct test *test, void *expected);
+
+/* Matches memory sections and strings. */
+struct mock_param_matcher *test_memeq(struct test *test,
+				      const void *buf,
+				      size_t size);
+struct mock_param_matcher *test_streq(struct test *test, const char *str);
+
+struct mock_action *test_u8_return(struct test *test, u8 ret);
+struct mock_action *test_u16_return(struct test *test, u16 ret);
+struct mock_action *test_u32_return(struct test *test, u32 ret);
+struct mock_action *test_u64_return(struct test *test, u64 ret);
+struct mock_action *test_char_return(struct test *test, char ret);
+struct mock_action *test_uchar_return(struct test *test, unsigned char ret);
+struct mock_action *test_schar_return(struct test *test, signed char ret);
+struct mock_action *test_short_return(struct test *test, short ret);
+struct mock_action *test_ushort_return(struct test *test, unsigned short ret);
+struct mock_action *test_int_return(struct test *test, int ret);
+struct mock_action *test_uint_return(struct test *test, unsigned int ret);
+struct mock_action *test_long_return(struct test *test, long ret);
+struct mock_action *test_ulong_return(struct test *test, unsigned long ret);
+struct mock_action *test_longlong_return(struct test *test, long long ret);
+struct mock_action *test_ulonglong_return(struct test *test,
+					  unsigned long long ret);
+struct mock_action *test_ptr_return(struct test *test, void *ret);
+
 #endif /* _KUNIT_MOCK_H */
diff --git a/kunit/Makefile b/kunit/Makefile
index ad58110de695c..52a1da46cbd21 100644
--- a/kunit/Makefile
+++ b/kunit/Makefile
@@ -1,4 +1,5 @@
-obj-$(CONFIG_KUNIT)		+= test.o mock.o string-stream.o test-stream.o
+obj-$(CONFIG_KUNIT)		+= test.o mock.o common-mocks.o string-stream.o \
+  test-stream.o
 obj-$(CONFIG_KUNIT_TEST)		+= \
   test-test.o mock-macro-test.o string-stream-test.o
 obj-$(CONFIG_EXAMPLE_TEST)	+= example-test.o
diff --git a/kunit/common-mocks.c b/kunit/common-mocks.c
new file mode 100644
index 0000000000000..ecac9c1c29c0e
--- /dev/null
+++ b/kunit/common-mocks.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common KUnit mock call arg matchers and formatters.
+ *
+ * Copyright (C) 2018, Google LLC.
+ * Author: Brendan Higgins <brendanhiggins at google.com>
+ */
+
+#include <linux/kernel.h>
+#include <kunit/mock.h>
+
+static bool match_any(struct mock_param_matcher *pmatcher,
+		      struct test_stream *stream,
+		      const void *actual)
+{
+	stream->add(stream, "don't care");
+	return true;
+}
+
+static struct mock_param_matcher any_matcher = {
+	.match = match_any,
+};
+
+struct mock_param_matcher *test_any(struct test *test)
+{
+	return &any_matcher;
+}
+
+#define DEFINE_MATCHER_STRUCT(type_name, type)				       \
+		struct mock_##type_name##_matcher {			       \
+			struct mock_param_matcher matcher;		       \
+			type expected;					       \
+		};
+
+#define DEFINE_TO_MATCHER_STRUCT(type_name)				       \
+		struct mock_##type_name##_matcher *			       \
+		to_mock_##type_name##_matcher(				       \
+				struct mock_param_matcher *matcher)	       \
+		{							       \
+			return container_of(matcher,			       \
+					    struct mock_##type_name##_matcher, \
+					    matcher);			       \
+		}
+
+#define DEFINE_MATCH_FUNC(type_name, type, op_name, op)			       \
+		bool match_##type_name##_##op_name(			       \
+				struct mock_param_matcher *pmatcher,	       \
+				struct test_stream *stream,		       \
+				const void *pactual)			       \
+		{							       \
+			struct mock_##type_name##_matcher *matcher =	       \
+				to_mock_##type_name##_matcher(pmatcher);       \
+			type actual = *((type *) pactual);		       \
+			bool matches = actual op matcher->expected;	       \
+									       \
+			if (matches)					       \
+				stream->add(stream,			       \
+					    "%d "#op" %d",		       \
+					    actual,			       \
+					    matcher->expected);		       \
+			else						       \
+				stream->add(stream,			       \
+					    "%d not "#op" %d",		       \
+					    actual,			       \
+					    matcher->expected);		       \
+									       \
+			return matches;					       \
+		}
+
+#define DEFINE_MATCH_FACTORY(type_name, type, op_name)			       \
+		struct mock_param_matcher *test_##type_name##_##op_name(       \
+				struct test *test, type expected)	       \
+		{							       \
+			struct mock_##type_name##_matcher *matcher;	       \
+									       \
+			matcher = test_kmalloc(test,			       \
+					       sizeof(*matcher),	       \
+					       GFP_KERNEL);		       \
+			if (!matcher)					       \
+				return NULL;				       \
+									       \
+			matcher->matcher.match = match_##type_name##_##op_name;\
+			matcher->expected = expected;			       \
+			return &matcher->matcher;			       \
+		}
+
+#define DEFINE_MATCHER_WITH_TYPENAME(type_name, type)			       \
+		DEFINE_MATCHER_STRUCT(type_name, type)			       \
+		DEFINE_TO_MATCHER_STRUCT(type_name)			       \
+		DEFINE_MATCH_FUNC(type_name, type, eq, ==)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, eq)		       \
+		DEFINE_MATCH_FUNC(type_name, type, ne, !=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, ne)		       \
+		DEFINE_MATCH_FUNC(type_name, type, le, <=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, le)		       \
+		DEFINE_MATCH_FUNC(type_name, type, lt, <)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, lt)		       \
+		DEFINE_MATCH_FUNC(type_name, type, ge, >=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, ge)		       \
+		DEFINE_MATCH_FUNC(type_name, type, gt, >)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, gt)
+
+#define DEFINE_MATCHER(type) DEFINE_MATCHER_WITH_TYPENAME(type, type)
+
+DEFINE_MATCHER(u8);
+DEFINE_MATCHER(u16);
+DEFINE_MATCHER(u32);
+DEFINE_MATCHER(u64);
+DEFINE_MATCHER(char);
+DEFINE_MATCHER_WITH_TYPENAME(uchar, unsigned char);
+DEFINE_MATCHER_WITH_TYPENAME(schar, signed char);
+DEFINE_MATCHER(short);
+DEFINE_MATCHER_WITH_TYPENAME(ushort, unsigned short);
+DEFINE_MATCHER(int);
+DEFINE_MATCHER_WITH_TYPENAME(uint, unsigned int);
+DEFINE_MATCHER(long);
+DEFINE_MATCHER_WITH_TYPENAME(ulong, unsigned long);
+DEFINE_MATCHER_WITH_TYPENAME(longlong, long long);
+DEFINE_MATCHER_WITH_TYPENAME(ulonglong, unsigned long long);
+
+DEFINE_MATCHER_WITH_TYPENAME(ptr, void *);
+
+struct mock_memeq_matcher {
+	struct mock_param_matcher matcher;
+	const void *expected;
+	size_t size;
+};
+
+static bool match_memeq(struct mock_param_matcher *pmatcher,
+			struct test_stream *stream,
+			const void *pactual)
+{
+	struct mock_memeq_matcher *matcher =
+			container_of(pmatcher,
+				     struct mock_memeq_matcher,
+				     matcher);
+	const void *actual = CONVERT_TO_ACTUAL_TYPE(const void *, pactual);
+	bool matches = !memcmp(actual, matcher->expected, matcher->size);
+	int i;
+
+	for (i = 0; i < matcher->size; i++)
+		stream->add(stream, "%02x, ", ((const char *) actual)[i]);
+	if (matches)
+		stream->add(stream, "== ");
+	else
+		stream->add(stream, "!= ");
+	for (i = 0; i < matcher->size; i++)
+		stream->add(stream,
+			    "%02x, ",
+			    ((const char *) matcher->expected)[i]);
+
+	return matches;
+}
+
+struct mock_param_matcher *test_memeq(struct test *test,
+				      const void *buf,
+				      size_t size)
+{
+	struct mock_memeq_matcher *matcher;
+
+	matcher = test_kzalloc(test, sizeof(*matcher), GFP_KERNEL);
+	if (!matcher)
+		return NULL;
+
+	matcher->matcher.match = match_memeq;
+	matcher->expected = buf;
+	matcher->size = size;
+
+	return &matcher->matcher;
+}
+
+struct mock_streq_matcher {
+	struct mock_param_matcher matcher;
+	const char *expected;
+};
+
+static bool match_streq(struct mock_param_matcher *pmatcher,
+			struct test_stream *stream,
+			const void *pactual)
+{
+	struct mock_streq_matcher *matcher =
+			container_of(pmatcher,
+				     struct mock_streq_matcher,
+				     matcher);
+	const char *actual = CONVERT_TO_ACTUAL_TYPE(const char *, pactual);
+	bool matches = !strcmp(actual, matcher->expected);
+
+	if (matches)
+		stream->add(stream, "%s == %s", actual, matcher->expected);
+	else
+		stream->add(stream, "%s != %s", actual, matcher->expected);
+
+	return matches;
+}
+
+struct mock_param_matcher *test_streq(struct test *test, const char *str)
+{
+	struct mock_streq_matcher *matcher;
+
+	matcher = test_kzalloc(test, sizeof(*matcher), GFP_KERNEL);
+	if (!matcher)
+		return NULL;
+
+	matcher->matcher.match = match_streq;
+	matcher->expected = str;
+
+	return &matcher->matcher;
+}
+
+#define DEFINE_RETURN_ACTION_STRUCT(type_name, type)			       \
+		struct mock_##type_name##_action {			       \
+			struct mock_action action;			       \
+			type ret;					       \
+		};
+
+#define DEFINE_RETURN_ACTION_FUNC(type_name, type)			       \
+		void *do_##type_name##_return(struct mock_action *paction,     \
+					      const void **params,	       \
+					      int len)			       \
+		{							       \
+			struct mock_##type_name##_action *action =	       \
+					container_of(paction,		       \
+						     struct mock_##type_name##_action,\
+						     action);		       \
+									       \
+			return (void *) &action->ret;			       \
+		}
+
+#define DEFINE_RETURN_ACTION_FACTORY(type_name, type)			       \
+		struct mock_action *test_##type_name##_return(		       \
+				struct test *test,			       \
+				type ret)				       \
+		{							       \
+			struct mock_##type_name##_action *action;	       \
+									       \
+			action = test_kmalloc(test,			       \
+					      sizeof(*action),		       \
+					      GFP_KERNEL);		       \
+			if (!action)					       \
+				return NULL;				       \
+									       \
+			action->action.do_action = do_##type_name##_return;    \
+			action->ret = ret;				       \
+									       \
+			return &action->action;				       \
+		}
+
+#define DEFINE_RETURN_ACTION_WITH_TYPENAME(type_name, type)		       \
+		DEFINE_RETURN_ACTION_STRUCT(type_name, type);		       \
+		DEFINE_RETURN_ACTION_FUNC(type_name, type);		       \
+		DEFINE_RETURN_ACTION_FACTORY(type_name, type);
+
+#define DEFINE_RETURN_ACTION(type) \
+		DEFINE_RETURN_ACTION_WITH_TYPENAME(type, type)
+
+DEFINE_RETURN_ACTION(u8);
+DEFINE_RETURN_ACTION(u16);
+DEFINE_RETURN_ACTION(u32);
+DEFINE_RETURN_ACTION(u64);
+DEFINE_RETURN_ACTION(char);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(uchar, unsigned char);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(schar, signed char);
+DEFINE_RETURN_ACTION(short);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ushort, unsigned short);
+DEFINE_RETURN_ACTION(int);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(uint, unsigned int);
+DEFINE_RETURN_ACTION(long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ulong, unsigned long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(longlong, long long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ulonglong, unsigned long long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ptr, void *);
+
-- 
2.19.1.331.ge82ca0e54c-goog

WARNING: multiple messages have this Message-ID (diff)
From: brendanhiggins@google.com (Brendan Higgins)
Subject: [RFC v1 15/31] kunit: mock: added basic matchers and actions
Date: Tue, 16 Oct 2018 16:51:04 -0700	[thread overview]
Message-ID: <20181016235120.138227-16-brendanhiggins@google.com> (raw)
Message-ID: <20181016235104.2rbkHHvvM3mOHVPPhnOkWD9GZgPEiXKtvUl_vYhtTyI@z> (raw)
In-Reply-To: <20181016235120.138227-1-brendanhiggins@google.com>

Added basic matchers and actions needed for any kind of mocking to be
useful; these matchers and actions are how expectations for mocks are
described: what calls the mocks are expected to receive, and what the
mock should do under those circumstances.

Signed-off-by: Brendan Higgins <brendanhiggins at google.com>
---
 include/kunit/mock.h | 222 +++++++++++++++++++++++++++++++++++
 kunit/Makefile       |   3 +-
 kunit/common-mocks.c | 272 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 496 insertions(+), 1 deletion(-)
 create mode 100644 kunit/common-mocks.c

diff --git a/include/kunit/mock.h b/include/kunit/mock.h
index 1a35c5702cb15..62e8afcaeab55 100644
--- a/include/kunit/mock.h
+++ b/include/kunit/mock.h
@@ -122,4 +122,226 @@ struct mock_expectation *mock_add_matcher(struct mock *mock,
 					  struct mock_param_matcher *matchers[],
 					  int len);
 
+#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 *test_int_eq(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_ne(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_lt(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_le(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_gt(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_ge(struct test *test, int expected);
+ *
+ * For a detailed list, please see
+ * ``include/linux/mock.h``.
+ */
+
+/* Matches any argument */
+struct mock_param_matcher *test_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 *test_u8_eq(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_ne(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_le(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_lt(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_ge(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_gt(struct test *test, u8 expected);
+
+struct mock_param_matcher *test_u16_eq(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_ne(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_le(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_lt(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_ge(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_gt(struct test *test, u16 expected);
+
+struct mock_param_matcher *test_u32_eq(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_ne(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_le(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_lt(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_ge(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_gt(struct test *test, u32 expected);
+
+struct mock_param_matcher *test_u64_eq(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_ne(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_le(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_lt(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_ge(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_gt(struct test *test, u64 expected);
+
+struct mock_param_matcher *test_char_eq(struct test *test, char expected);
+struct mock_param_matcher *test_char_ne(struct test *test, char expected);
+struct mock_param_matcher *test_char_le(struct test *test, char expected);
+struct mock_param_matcher *test_char_lt(struct test *test, char expected);
+struct mock_param_matcher *test_char_ge(struct test *test, char expected);
+struct mock_param_matcher *test_char_gt(struct test *test, char expected);
+
+struct mock_param_matcher *test_uchar_eq(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_ne(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_le(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_lt(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_ge(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_gt(struct test *test,
+					 unsigned char expected);
+
+struct mock_param_matcher *test_schar_eq(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_ne(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_le(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_lt(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_ge(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_gt(struct test *test,
+					 signed char expected);
+
+struct mock_param_matcher *test_short_eq(struct test *test, short expected);
+struct mock_param_matcher *test_short_ne(struct test *test, short expected);
+struct mock_param_matcher *test_short_le(struct test *test, short expected);
+struct mock_param_matcher *test_short_lt(struct test *test, short expected);
+struct mock_param_matcher *test_short_ge(struct test *test, short expected);
+struct mock_param_matcher *test_short_gt(struct test *test, short expected);
+
+struct mock_param_matcher *test_ushort_eq(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_ne(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_le(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_lt(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_ge(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_gt(struct test *test,
+					  unsigned short expected);
+
+struct mock_param_matcher *test_int_eq(struct test *test, int expected);
+struct mock_param_matcher *test_int_ne(struct test *test, int expected);
+struct mock_param_matcher *test_int_lt(struct test *test, int expected);
+struct mock_param_matcher *test_int_le(struct test *test, int expected);
+struct mock_param_matcher *test_int_gt(struct test *test, int expected);
+struct mock_param_matcher *test_int_ge(struct test *test, int expected);
+
+struct mock_param_matcher *test_uint_eq(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_ne(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_lt(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_le(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_gt(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_ge(struct test *test,
+					unsigned int expected);
+
+struct mock_param_matcher *test_long_eq(struct test *test, long expected);
+struct mock_param_matcher *test_long_ne(struct test *test, long expected);
+struct mock_param_matcher *test_long_le(struct test *test, long expected);
+struct mock_param_matcher *test_long_lt(struct test *test, long expected);
+struct mock_param_matcher *test_long_ge(struct test *test, long expected);
+struct mock_param_matcher *test_long_gt(struct test *test, long expected);
+
+struct mock_param_matcher *test_ulong_eq(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_ne(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_le(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_lt(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_ge(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_gt(struct test *test,
+					 unsigned long expected);
+
+struct mock_param_matcher *test_longlong_eq(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_ne(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_le(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_lt(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_ge(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_gt(struct test *test,
+					    long long expected);
+
+struct mock_param_matcher *test_ulonglong_eq(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_ne(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_le(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_lt(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_ge(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_gt(struct test *test,
+					     unsigned long long expected);
+
+/* Matches pointers. */
+struct mock_param_matcher *test_ptr_eq(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_ne(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_lt(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_le(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_gt(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_ge(struct test *test, void *expected);
+
+/* Matches memory sections and strings. */
+struct mock_param_matcher *test_memeq(struct test *test,
+				      const void *buf,
+				      size_t size);
+struct mock_param_matcher *test_streq(struct test *test, const char *str);
+
+struct mock_action *test_u8_return(struct test *test, u8 ret);
+struct mock_action *test_u16_return(struct test *test, u16 ret);
+struct mock_action *test_u32_return(struct test *test, u32 ret);
+struct mock_action *test_u64_return(struct test *test, u64 ret);
+struct mock_action *test_char_return(struct test *test, char ret);
+struct mock_action *test_uchar_return(struct test *test, unsigned char ret);
+struct mock_action *test_schar_return(struct test *test, signed char ret);
+struct mock_action *test_short_return(struct test *test, short ret);
+struct mock_action *test_ushort_return(struct test *test, unsigned short ret);
+struct mock_action *test_int_return(struct test *test, int ret);
+struct mock_action *test_uint_return(struct test *test, unsigned int ret);
+struct mock_action *test_long_return(struct test *test, long ret);
+struct mock_action *test_ulong_return(struct test *test, unsigned long ret);
+struct mock_action *test_longlong_return(struct test *test, long long ret);
+struct mock_action *test_ulonglong_return(struct test *test,
+					  unsigned long long ret);
+struct mock_action *test_ptr_return(struct test *test, void *ret);
+
 #endif /* _KUNIT_MOCK_H */
diff --git a/kunit/Makefile b/kunit/Makefile
index ad58110de695c..52a1da46cbd21 100644
--- a/kunit/Makefile
+++ b/kunit/Makefile
@@ -1,4 +1,5 @@
-obj-$(CONFIG_KUNIT)		+= test.o mock.o string-stream.o test-stream.o
+obj-$(CONFIG_KUNIT)		+= test.o mock.o common-mocks.o string-stream.o \
+  test-stream.o
 obj-$(CONFIG_KUNIT_TEST)		+= \
   test-test.o mock-macro-test.o string-stream-test.o
 obj-$(CONFIG_EXAMPLE_TEST)	+= example-test.o
diff --git a/kunit/common-mocks.c b/kunit/common-mocks.c
new file mode 100644
index 0000000000000..ecac9c1c29c0e
--- /dev/null
+++ b/kunit/common-mocks.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common KUnit mock call arg matchers and formatters.
+ *
+ * Copyright (C) 2018, Google LLC.
+ * Author: Brendan Higgins <brendanhiggins at google.com>
+ */
+
+#include <linux/kernel.h>
+#include <kunit/mock.h>
+
+static bool match_any(struct mock_param_matcher *pmatcher,
+		      struct test_stream *stream,
+		      const void *actual)
+{
+	stream->add(stream, "don't care");
+	return true;
+}
+
+static struct mock_param_matcher any_matcher = {
+	.match = match_any,
+};
+
+struct mock_param_matcher *test_any(struct test *test)
+{
+	return &any_matcher;
+}
+
+#define DEFINE_MATCHER_STRUCT(type_name, type)				       \
+		struct mock_##type_name##_matcher {			       \
+			struct mock_param_matcher matcher;		       \
+			type expected;					       \
+		};
+
+#define DEFINE_TO_MATCHER_STRUCT(type_name)				       \
+		struct mock_##type_name##_matcher *			       \
+		to_mock_##type_name##_matcher(				       \
+				struct mock_param_matcher *matcher)	       \
+		{							       \
+			return container_of(matcher,			       \
+					    struct mock_##type_name##_matcher, \
+					    matcher);			       \
+		}
+
+#define DEFINE_MATCH_FUNC(type_name, type, op_name, op)			       \
+		bool match_##type_name##_##op_name(			       \
+				struct mock_param_matcher *pmatcher,	       \
+				struct test_stream *stream,		       \
+				const void *pactual)			       \
+		{							       \
+			struct mock_##type_name##_matcher *matcher =	       \
+				to_mock_##type_name##_matcher(pmatcher);       \
+			type actual = *((type *) pactual);		       \
+			bool matches = actual op matcher->expected;	       \
+									       \
+			if (matches)					       \
+				stream->add(stream,			       \
+					    "%d "#op" %d",		       \
+					    actual,			       \
+					    matcher->expected);		       \
+			else						       \
+				stream->add(stream,			       \
+					    "%d not "#op" %d",		       \
+					    actual,			       \
+					    matcher->expected);		       \
+									       \
+			return matches;					       \
+		}
+
+#define DEFINE_MATCH_FACTORY(type_name, type, op_name)			       \
+		struct mock_param_matcher *test_##type_name##_##op_name(       \
+				struct test *test, type expected)	       \
+		{							       \
+			struct mock_##type_name##_matcher *matcher;	       \
+									       \
+			matcher = test_kmalloc(test,			       \
+					       sizeof(*matcher),	       \
+					       GFP_KERNEL);		       \
+			if (!matcher)					       \
+				return NULL;				       \
+									       \
+			matcher->matcher.match = match_##type_name##_##op_name;\
+			matcher->expected = expected;			       \
+			return &matcher->matcher;			       \
+		}
+
+#define DEFINE_MATCHER_WITH_TYPENAME(type_name, type)			       \
+		DEFINE_MATCHER_STRUCT(type_name, type)			       \
+		DEFINE_TO_MATCHER_STRUCT(type_name)			       \
+		DEFINE_MATCH_FUNC(type_name, type, eq, ==)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, eq)		       \
+		DEFINE_MATCH_FUNC(type_name, type, ne, !=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, ne)		       \
+		DEFINE_MATCH_FUNC(type_name, type, le, <=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, le)		       \
+		DEFINE_MATCH_FUNC(type_name, type, lt, <)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, lt)		       \
+		DEFINE_MATCH_FUNC(type_name, type, ge, >=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, ge)		       \
+		DEFINE_MATCH_FUNC(type_name, type, gt, >)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, gt)
+
+#define DEFINE_MATCHER(type) DEFINE_MATCHER_WITH_TYPENAME(type, type)
+
+DEFINE_MATCHER(u8);
+DEFINE_MATCHER(u16);
+DEFINE_MATCHER(u32);
+DEFINE_MATCHER(u64);
+DEFINE_MATCHER(char);
+DEFINE_MATCHER_WITH_TYPENAME(uchar, unsigned char);
+DEFINE_MATCHER_WITH_TYPENAME(schar, signed char);
+DEFINE_MATCHER(short);
+DEFINE_MATCHER_WITH_TYPENAME(ushort, unsigned short);
+DEFINE_MATCHER(int);
+DEFINE_MATCHER_WITH_TYPENAME(uint, unsigned int);
+DEFINE_MATCHER(long);
+DEFINE_MATCHER_WITH_TYPENAME(ulong, unsigned long);
+DEFINE_MATCHER_WITH_TYPENAME(longlong, long long);
+DEFINE_MATCHER_WITH_TYPENAME(ulonglong, unsigned long long);
+
+DEFINE_MATCHER_WITH_TYPENAME(ptr, void *);
+
+struct mock_memeq_matcher {
+	struct mock_param_matcher matcher;
+	const void *expected;
+	size_t size;
+};
+
+static bool match_memeq(struct mock_param_matcher *pmatcher,
+			struct test_stream *stream,
+			const void *pactual)
+{
+	struct mock_memeq_matcher *matcher =
+			container_of(pmatcher,
+				     struct mock_memeq_matcher,
+				     matcher);
+	const void *actual = CONVERT_TO_ACTUAL_TYPE(const void *, pactual);
+	bool matches = !memcmp(actual, matcher->expected, matcher->size);
+	int i;
+
+	for (i = 0; i < matcher->size; i++)
+		stream->add(stream, "%02x, ", ((const char *) actual)[i]);
+	if (matches)
+		stream->add(stream, "== ");
+	else
+		stream->add(stream, "!= ");
+	for (i = 0; i < matcher->size; i++)
+		stream->add(stream,
+			    "%02x, ",
+			    ((const char *) matcher->expected)[i]);
+
+	return matches;
+}
+
+struct mock_param_matcher *test_memeq(struct test *test,
+				      const void *buf,
+				      size_t size)
+{
+	struct mock_memeq_matcher *matcher;
+
+	matcher = test_kzalloc(test, sizeof(*matcher), GFP_KERNEL);
+	if (!matcher)
+		return NULL;
+
+	matcher->matcher.match = match_memeq;
+	matcher->expected = buf;
+	matcher->size = size;
+
+	return &matcher->matcher;
+}
+
+struct mock_streq_matcher {
+	struct mock_param_matcher matcher;
+	const char *expected;
+};
+
+static bool match_streq(struct mock_param_matcher *pmatcher,
+			struct test_stream *stream,
+			const void *pactual)
+{
+	struct mock_streq_matcher *matcher =
+			container_of(pmatcher,
+				     struct mock_streq_matcher,
+				     matcher);
+	const char *actual = CONVERT_TO_ACTUAL_TYPE(const char *, pactual);
+	bool matches = !strcmp(actual, matcher->expected);
+
+	if (matches)
+		stream->add(stream, "%s == %s", actual, matcher->expected);
+	else
+		stream->add(stream, "%s != %s", actual, matcher->expected);
+
+	return matches;
+}
+
+struct mock_param_matcher *test_streq(struct test *test, const char *str)
+{
+	struct mock_streq_matcher *matcher;
+
+	matcher = test_kzalloc(test, sizeof(*matcher), GFP_KERNEL);
+	if (!matcher)
+		return NULL;
+
+	matcher->matcher.match = match_streq;
+	matcher->expected = str;
+
+	return &matcher->matcher;
+}
+
+#define DEFINE_RETURN_ACTION_STRUCT(type_name, type)			       \
+		struct mock_##type_name##_action {			       \
+			struct mock_action action;			       \
+			type ret;					       \
+		};
+
+#define DEFINE_RETURN_ACTION_FUNC(type_name, type)			       \
+		void *do_##type_name##_return(struct mock_action *paction,     \
+					      const void **params,	       \
+					      int len)			       \
+		{							       \
+			struct mock_##type_name##_action *action =	       \
+					container_of(paction,		       \
+						     struct mock_##type_name##_action,\
+						     action);		       \
+									       \
+			return (void *) &action->ret;			       \
+		}
+
+#define DEFINE_RETURN_ACTION_FACTORY(type_name, type)			       \
+		struct mock_action *test_##type_name##_return(		       \
+				struct test *test,			       \
+				type ret)				       \
+		{							       \
+			struct mock_##type_name##_action *action;	       \
+									       \
+			action = test_kmalloc(test,			       \
+					      sizeof(*action),		       \
+					      GFP_KERNEL);		       \
+			if (!action)					       \
+				return NULL;				       \
+									       \
+			action->action.do_action = do_##type_name##_return;    \
+			action->ret = ret;				       \
+									       \
+			return &action->action;				       \
+		}
+
+#define DEFINE_RETURN_ACTION_WITH_TYPENAME(type_name, type)		       \
+		DEFINE_RETURN_ACTION_STRUCT(type_name, type);		       \
+		DEFINE_RETURN_ACTION_FUNC(type_name, type);		       \
+		DEFINE_RETURN_ACTION_FACTORY(type_name, type);
+
+#define DEFINE_RETURN_ACTION(type) \
+		DEFINE_RETURN_ACTION_WITH_TYPENAME(type, type)
+
+DEFINE_RETURN_ACTION(u8);
+DEFINE_RETURN_ACTION(u16);
+DEFINE_RETURN_ACTION(u32);
+DEFINE_RETURN_ACTION(u64);
+DEFINE_RETURN_ACTION(char);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(uchar, unsigned char);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(schar, signed char);
+DEFINE_RETURN_ACTION(short);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ushort, unsigned short);
+DEFINE_RETURN_ACTION(int);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(uint, unsigned int);
+DEFINE_RETURN_ACTION(long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ulong, unsigned long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(longlong, long long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ulonglong, unsigned long long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ptr, void *);
+
-- 
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 15/31] kunit: mock: added basic matchers and actions
Date: Tue, 16 Oct 2018 16:51:04 -0700	[thread overview]
Message-ID: <20181016235120.138227-16-brendanhiggins@google.com> (raw)
In-Reply-To: <20181016235120.138227-1-brendanhiggins@google.com>

Added basic matchers and actions needed for any kind of mocking to be
useful; these matchers and actions are how expectations for mocks are
described: what calls the mocks are expected to receive, and what the
mock should do under those circumstances.

Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
---
 include/kunit/mock.h | 222 +++++++++++++++++++++++++++++++++++
 kunit/Makefile       |   3 +-
 kunit/common-mocks.c | 272 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 496 insertions(+), 1 deletion(-)
 create mode 100644 kunit/common-mocks.c

diff --git a/include/kunit/mock.h b/include/kunit/mock.h
index 1a35c5702cb15..62e8afcaeab55 100644
--- a/include/kunit/mock.h
+++ b/include/kunit/mock.h
@@ -122,4 +122,226 @@ struct mock_expectation *mock_add_matcher(struct mock *mock,
 					  struct mock_param_matcher *matchers[],
 					  int len);
 
+#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 *test_int_eq(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_ne(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_lt(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_le(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_gt(struct test *test, int expected);
+ *    struct mock_param_matcher *test_int_ge(struct test *test, int expected);
+ *
+ * For a detailed list, please see
+ * ``include/linux/mock.h``.
+ */
+
+/* Matches any argument */
+struct mock_param_matcher *test_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 *test_u8_eq(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_ne(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_le(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_lt(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_ge(struct test *test, u8 expected);
+struct mock_param_matcher *test_u8_gt(struct test *test, u8 expected);
+
+struct mock_param_matcher *test_u16_eq(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_ne(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_le(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_lt(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_ge(struct test *test, u16 expected);
+struct mock_param_matcher *test_u16_gt(struct test *test, u16 expected);
+
+struct mock_param_matcher *test_u32_eq(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_ne(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_le(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_lt(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_ge(struct test *test, u32 expected);
+struct mock_param_matcher *test_u32_gt(struct test *test, u32 expected);
+
+struct mock_param_matcher *test_u64_eq(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_ne(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_le(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_lt(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_ge(struct test *test, u64 expected);
+struct mock_param_matcher *test_u64_gt(struct test *test, u64 expected);
+
+struct mock_param_matcher *test_char_eq(struct test *test, char expected);
+struct mock_param_matcher *test_char_ne(struct test *test, char expected);
+struct mock_param_matcher *test_char_le(struct test *test, char expected);
+struct mock_param_matcher *test_char_lt(struct test *test, char expected);
+struct mock_param_matcher *test_char_ge(struct test *test, char expected);
+struct mock_param_matcher *test_char_gt(struct test *test, char expected);
+
+struct mock_param_matcher *test_uchar_eq(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_ne(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_le(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_lt(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_ge(struct test *test,
+					 unsigned char expected);
+struct mock_param_matcher *test_uchar_gt(struct test *test,
+					 unsigned char expected);
+
+struct mock_param_matcher *test_schar_eq(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_ne(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_le(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_lt(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_ge(struct test *test,
+					 signed char expected);
+struct mock_param_matcher *test_schar_gt(struct test *test,
+					 signed char expected);
+
+struct mock_param_matcher *test_short_eq(struct test *test, short expected);
+struct mock_param_matcher *test_short_ne(struct test *test, short expected);
+struct mock_param_matcher *test_short_le(struct test *test, short expected);
+struct mock_param_matcher *test_short_lt(struct test *test, short expected);
+struct mock_param_matcher *test_short_ge(struct test *test, short expected);
+struct mock_param_matcher *test_short_gt(struct test *test, short expected);
+
+struct mock_param_matcher *test_ushort_eq(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_ne(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_le(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_lt(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_ge(struct test *test,
+					  unsigned short expected);
+struct mock_param_matcher *test_ushort_gt(struct test *test,
+					  unsigned short expected);
+
+struct mock_param_matcher *test_int_eq(struct test *test, int expected);
+struct mock_param_matcher *test_int_ne(struct test *test, int expected);
+struct mock_param_matcher *test_int_lt(struct test *test, int expected);
+struct mock_param_matcher *test_int_le(struct test *test, int expected);
+struct mock_param_matcher *test_int_gt(struct test *test, int expected);
+struct mock_param_matcher *test_int_ge(struct test *test, int expected);
+
+struct mock_param_matcher *test_uint_eq(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_ne(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_lt(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_le(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_gt(struct test *test,
+					unsigned int expected);
+struct mock_param_matcher *test_uint_ge(struct test *test,
+					unsigned int expected);
+
+struct mock_param_matcher *test_long_eq(struct test *test, long expected);
+struct mock_param_matcher *test_long_ne(struct test *test, long expected);
+struct mock_param_matcher *test_long_le(struct test *test, long expected);
+struct mock_param_matcher *test_long_lt(struct test *test, long expected);
+struct mock_param_matcher *test_long_ge(struct test *test, long expected);
+struct mock_param_matcher *test_long_gt(struct test *test, long expected);
+
+struct mock_param_matcher *test_ulong_eq(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_ne(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_le(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_lt(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_ge(struct test *test,
+					 unsigned long expected);
+struct mock_param_matcher *test_ulong_gt(struct test *test,
+					 unsigned long expected);
+
+struct mock_param_matcher *test_longlong_eq(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_ne(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_le(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_lt(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_ge(struct test *test,
+					    long long expected);
+struct mock_param_matcher *test_longlong_gt(struct test *test,
+					    long long expected);
+
+struct mock_param_matcher *test_ulonglong_eq(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_ne(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_le(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_lt(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_ge(struct test *test,
+					     unsigned long long expected);
+struct mock_param_matcher *test_ulonglong_gt(struct test *test,
+					     unsigned long long expected);
+
+/* Matches pointers. */
+struct mock_param_matcher *test_ptr_eq(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_ne(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_lt(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_le(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_gt(struct test *test, void *expected);
+struct mock_param_matcher *test_ptr_ge(struct test *test, void *expected);
+
+/* Matches memory sections and strings. */
+struct mock_param_matcher *test_memeq(struct test *test,
+				      const void *buf,
+				      size_t size);
+struct mock_param_matcher *test_streq(struct test *test, const char *str);
+
+struct mock_action *test_u8_return(struct test *test, u8 ret);
+struct mock_action *test_u16_return(struct test *test, u16 ret);
+struct mock_action *test_u32_return(struct test *test, u32 ret);
+struct mock_action *test_u64_return(struct test *test, u64 ret);
+struct mock_action *test_char_return(struct test *test, char ret);
+struct mock_action *test_uchar_return(struct test *test, unsigned char ret);
+struct mock_action *test_schar_return(struct test *test, signed char ret);
+struct mock_action *test_short_return(struct test *test, short ret);
+struct mock_action *test_ushort_return(struct test *test, unsigned short ret);
+struct mock_action *test_int_return(struct test *test, int ret);
+struct mock_action *test_uint_return(struct test *test, unsigned int ret);
+struct mock_action *test_long_return(struct test *test, long ret);
+struct mock_action *test_ulong_return(struct test *test, unsigned long ret);
+struct mock_action *test_longlong_return(struct test *test, long long ret);
+struct mock_action *test_ulonglong_return(struct test *test,
+					  unsigned long long ret);
+struct mock_action *test_ptr_return(struct test *test, void *ret);
+
 #endif /* _KUNIT_MOCK_H */
diff --git a/kunit/Makefile b/kunit/Makefile
index ad58110de695c..52a1da46cbd21 100644
--- a/kunit/Makefile
+++ b/kunit/Makefile
@@ -1,4 +1,5 @@
-obj-$(CONFIG_KUNIT)		+= test.o mock.o string-stream.o test-stream.o
+obj-$(CONFIG_KUNIT)		+= test.o mock.o common-mocks.o string-stream.o \
+  test-stream.o
 obj-$(CONFIG_KUNIT_TEST)		+= \
   test-test.o mock-macro-test.o string-stream-test.o
 obj-$(CONFIG_EXAMPLE_TEST)	+= example-test.o
diff --git a/kunit/common-mocks.c b/kunit/common-mocks.c
new file mode 100644
index 0000000000000..ecac9c1c29c0e
--- /dev/null
+++ b/kunit/common-mocks.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common KUnit mock call arg matchers and formatters.
+ *
+ * Copyright (C) 2018, Google LLC.
+ * Author: Brendan Higgins <brendanhiggins@google.com>
+ */
+
+#include <linux/kernel.h>
+#include <kunit/mock.h>
+
+static bool match_any(struct mock_param_matcher *pmatcher,
+		      struct test_stream *stream,
+		      const void *actual)
+{
+	stream->add(stream, "don't care");
+	return true;
+}
+
+static struct mock_param_matcher any_matcher = {
+	.match = match_any,
+};
+
+struct mock_param_matcher *test_any(struct test *test)
+{
+	return &any_matcher;
+}
+
+#define DEFINE_MATCHER_STRUCT(type_name, type)				       \
+		struct mock_##type_name##_matcher {			       \
+			struct mock_param_matcher matcher;		       \
+			type expected;					       \
+		};
+
+#define DEFINE_TO_MATCHER_STRUCT(type_name)				       \
+		struct mock_##type_name##_matcher *			       \
+		to_mock_##type_name##_matcher(				       \
+				struct mock_param_matcher *matcher)	       \
+		{							       \
+			return container_of(matcher,			       \
+					    struct mock_##type_name##_matcher, \
+					    matcher);			       \
+		}
+
+#define DEFINE_MATCH_FUNC(type_name, type, op_name, op)			       \
+		bool match_##type_name##_##op_name(			       \
+				struct mock_param_matcher *pmatcher,	       \
+				struct test_stream *stream,		       \
+				const void *pactual)			       \
+		{							       \
+			struct mock_##type_name##_matcher *matcher =	       \
+				to_mock_##type_name##_matcher(pmatcher);       \
+			type actual = *((type *) pactual);		       \
+			bool matches = actual op matcher->expected;	       \
+									       \
+			if (matches)					       \
+				stream->add(stream,			       \
+					    "%d "#op" %d",		       \
+					    actual,			       \
+					    matcher->expected);		       \
+			else						       \
+				stream->add(stream,			       \
+					    "%d not "#op" %d",		       \
+					    actual,			       \
+					    matcher->expected);		       \
+									       \
+			return matches;					       \
+		}
+
+#define DEFINE_MATCH_FACTORY(type_name, type, op_name)			       \
+		struct mock_param_matcher *test_##type_name##_##op_name(       \
+				struct test *test, type expected)	       \
+		{							       \
+			struct mock_##type_name##_matcher *matcher;	       \
+									       \
+			matcher = test_kmalloc(test,			       \
+					       sizeof(*matcher),	       \
+					       GFP_KERNEL);		       \
+			if (!matcher)					       \
+				return NULL;				       \
+									       \
+			matcher->matcher.match = match_##type_name##_##op_name;\
+			matcher->expected = expected;			       \
+			return &matcher->matcher;			       \
+		}
+
+#define DEFINE_MATCHER_WITH_TYPENAME(type_name, type)			       \
+		DEFINE_MATCHER_STRUCT(type_name, type)			       \
+		DEFINE_TO_MATCHER_STRUCT(type_name)			       \
+		DEFINE_MATCH_FUNC(type_name, type, eq, ==)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, eq)		       \
+		DEFINE_MATCH_FUNC(type_name, type, ne, !=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, ne)		       \
+		DEFINE_MATCH_FUNC(type_name, type, le, <=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, le)		       \
+		DEFINE_MATCH_FUNC(type_name, type, lt, <)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, lt)		       \
+		DEFINE_MATCH_FUNC(type_name, type, ge, >=)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, ge)		       \
+		DEFINE_MATCH_FUNC(type_name, type, gt, >)		       \
+		DEFINE_MATCH_FACTORY(type_name, type, gt)
+
+#define DEFINE_MATCHER(type) DEFINE_MATCHER_WITH_TYPENAME(type, type)
+
+DEFINE_MATCHER(u8);
+DEFINE_MATCHER(u16);
+DEFINE_MATCHER(u32);
+DEFINE_MATCHER(u64);
+DEFINE_MATCHER(char);
+DEFINE_MATCHER_WITH_TYPENAME(uchar, unsigned char);
+DEFINE_MATCHER_WITH_TYPENAME(schar, signed char);
+DEFINE_MATCHER(short);
+DEFINE_MATCHER_WITH_TYPENAME(ushort, unsigned short);
+DEFINE_MATCHER(int);
+DEFINE_MATCHER_WITH_TYPENAME(uint, unsigned int);
+DEFINE_MATCHER(long);
+DEFINE_MATCHER_WITH_TYPENAME(ulong, unsigned long);
+DEFINE_MATCHER_WITH_TYPENAME(longlong, long long);
+DEFINE_MATCHER_WITH_TYPENAME(ulonglong, unsigned long long);
+
+DEFINE_MATCHER_WITH_TYPENAME(ptr, void *);
+
+struct mock_memeq_matcher {
+	struct mock_param_matcher matcher;
+	const void *expected;
+	size_t size;
+};
+
+static bool match_memeq(struct mock_param_matcher *pmatcher,
+			struct test_stream *stream,
+			const void *pactual)
+{
+	struct mock_memeq_matcher *matcher =
+			container_of(pmatcher,
+				     struct mock_memeq_matcher,
+				     matcher);
+	const void *actual = CONVERT_TO_ACTUAL_TYPE(const void *, pactual);
+	bool matches = !memcmp(actual, matcher->expected, matcher->size);
+	int i;
+
+	for (i = 0; i < matcher->size; i++)
+		stream->add(stream, "%02x, ", ((const char *) actual)[i]);
+	if (matches)
+		stream->add(stream, "== ");
+	else
+		stream->add(stream, "!= ");
+	for (i = 0; i < matcher->size; i++)
+		stream->add(stream,
+			    "%02x, ",
+			    ((const char *) matcher->expected)[i]);
+
+	return matches;
+}
+
+struct mock_param_matcher *test_memeq(struct test *test,
+				      const void *buf,
+				      size_t size)
+{
+	struct mock_memeq_matcher *matcher;
+
+	matcher = test_kzalloc(test, sizeof(*matcher), GFP_KERNEL);
+	if (!matcher)
+		return NULL;
+
+	matcher->matcher.match = match_memeq;
+	matcher->expected = buf;
+	matcher->size = size;
+
+	return &matcher->matcher;
+}
+
+struct mock_streq_matcher {
+	struct mock_param_matcher matcher;
+	const char *expected;
+};
+
+static bool match_streq(struct mock_param_matcher *pmatcher,
+			struct test_stream *stream,
+			const void *pactual)
+{
+	struct mock_streq_matcher *matcher =
+			container_of(pmatcher,
+				     struct mock_streq_matcher,
+				     matcher);
+	const char *actual = CONVERT_TO_ACTUAL_TYPE(const char *, pactual);
+	bool matches = !strcmp(actual, matcher->expected);
+
+	if (matches)
+		stream->add(stream, "%s == %s", actual, matcher->expected);
+	else
+		stream->add(stream, "%s != %s", actual, matcher->expected);
+
+	return matches;
+}
+
+struct mock_param_matcher *test_streq(struct test *test, const char *str)
+{
+	struct mock_streq_matcher *matcher;
+
+	matcher = test_kzalloc(test, sizeof(*matcher), GFP_KERNEL);
+	if (!matcher)
+		return NULL;
+
+	matcher->matcher.match = match_streq;
+	matcher->expected = str;
+
+	return &matcher->matcher;
+}
+
+#define DEFINE_RETURN_ACTION_STRUCT(type_name, type)			       \
+		struct mock_##type_name##_action {			       \
+			struct mock_action action;			       \
+			type ret;					       \
+		};
+
+#define DEFINE_RETURN_ACTION_FUNC(type_name, type)			       \
+		void *do_##type_name##_return(struct mock_action *paction,     \
+					      const void **params,	       \
+					      int len)			       \
+		{							       \
+			struct mock_##type_name##_action *action =	       \
+					container_of(paction,		       \
+						     struct mock_##type_name##_action,\
+						     action);		       \
+									       \
+			return (void *) &action->ret;			       \
+		}
+
+#define DEFINE_RETURN_ACTION_FACTORY(type_name, type)			       \
+		struct mock_action *test_##type_name##_return(		       \
+				struct test *test,			       \
+				type ret)				       \
+		{							       \
+			struct mock_##type_name##_action *action;	       \
+									       \
+			action = test_kmalloc(test,			       \
+					      sizeof(*action),		       \
+					      GFP_KERNEL);		       \
+			if (!action)					       \
+				return NULL;				       \
+									       \
+			action->action.do_action = do_##type_name##_return;    \
+			action->ret = ret;				       \
+									       \
+			return &action->action;				       \
+		}
+
+#define DEFINE_RETURN_ACTION_WITH_TYPENAME(type_name, type)		       \
+		DEFINE_RETURN_ACTION_STRUCT(type_name, type);		       \
+		DEFINE_RETURN_ACTION_FUNC(type_name, type);		       \
+		DEFINE_RETURN_ACTION_FACTORY(type_name, type);
+
+#define DEFINE_RETURN_ACTION(type) \
+		DEFINE_RETURN_ACTION_WITH_TYPENAME(type, type)
+
+DEFINE_RETURN_ACTION(u8);
+DEFINE_RETURN_ACTION(u16);
+DEFINE_RETURN_ACTION(u32);
+DEFINE_RETURN_ACTION(u64);
+DEFINE_RETURN_ACTION(char);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(uchar, unsigned char);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(schar, signed char);
+DEFINE_RETURN_ACTION(short);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ushort, unsigned short);
+DEFINE_RETURN_ACTION(int);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(uint, unsigned int);
+DEFINE_RETURN_ACTION(long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ulong, unsigned long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(longlong, long long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ulonglong, unsigned long long);
+DEFINE_RETURN_ACTION_WITH_TYPENAME(ptr, void *);
+
-- 
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 ` Brendan Higgins [this message]
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   ` 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 ` [RFC v1 23/31] kunit: mock: add parameter capturers 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 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-16-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.