All of lore.kernel.org
 help / color / mirror / Atom feed
* [Linux-kernel-mentees] [RFC v2 1/2] kunit: Support for Parameterized Testing
@ 2020-09-30 14:40 Arpitha Raghunandan
  2020-10-01  3:21 ` [Linux-kernel-mentees] [RFC v2 2/2] fs: ext4: Modify inode-test.c to use KUnit parameterized testing Arpitha Raghunandan
  0 siblings, 1 reply; 2+ messages in thread
From: Arpitha Raghunandan @ 2020-09-30 14:40 UTC (permalink / raw)
  To: brendanhiggins, tytso, adilger.kernel, skhan
  Cc: Arpitha Raghunandan, linux-kernel-mentees, kunit-dev

This patch has a basic implementation for adding support for
parameterized testing in KUnit. The macro KUNIT_CASE_PARAM takes
in a function pointer to a function that returns the test case
parameters, the number of test cases and the size of each test 
case parameter. The get_test_case_parameters() acts as an iterator
and returns one test case parameter each time it is called.


Signed-off-by: Arpitha Raghunandan <98.arpi@gmail.com>
---
Changes v1->v2:
- Parameterized input stored in a void* array
- An iterator method to access the different parameters

 include/kunit/test.h | 17 +++++++++++++++++
 lib/kunit/test.c     | 27 +++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/include/kunit/test.h b/include/kunit/test.h
index 59f3144f009a..d037ba8c3002 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -140,10 +140,14 @@ struct kunit;
 struct kunit_case {
 	void (*run_case)(struct kunit *test);
 	const char *name;
+	void* (*get_params)(void);
+	int max_parameters_count;
+	int parameter_size;
 
 	/* private: internal use only. */
 	bool success;
 	char *log;
+	bool parameterized;
 };
 
 static inline char *kunit_status_to_string(bool status)
@@ -162,6 +166,11 @@ static inline char *kunit_status_to_string(bool status)
  */
 #define KUNIT_CASE(test_name) { .run_case = test_name, .name = #test_name }
 
+#define KUNIT_CASE_PARAM(test_name, getparams, count, size) {	.run_case = test_name,						\
+								.name = #test_name, .parameterized = true,			\
+								.get_params = (void* (*)(void))getparams,			\
+								.max_parameters_count = count, .parameter_size = size }
+
 /**
  * struct kunit_suite - describes a related collection of &struct kunit_case
  *
@@ -206,6 +215,11 @@ struct kunit {
 	/* private: internal use only. */
 	const char *name; /* Read only after initialization! */
 	char *log; /* Points at case log after initialization */
+	bool parameterized; /* True for parameterized tests */
+	void *param_values; /* Stores the test parameters for parameterized tests */
+	int max_parameters_count; /* Indicates maximum number of parameters for parameterized tests */
+	int iterator_count; /* Used by the iterator method for parameterized tests */
+	int parameter_size; /* Indicates size of a single test case for parameterized tests */
 	struct kunit_try_catch try_catch;
 	/*
 	 * success starts as true, and may only be set to false during a
@@ -225,6 +239,7 @@ struct kunit {
 };
 
 void kunit_init_test(struct kunit *test, const char *name, char *log);
+void kunit_init_param_test(struct kunit *test, struct kunit_case *test_case);
 
 int kunit_run_tests(struct kunit_suite *suite);
 
@@ -237,6 +252,8 @@ int __kunit_test_suites_init(struct kunit_suite **suites);
 
 void __kunit_test_suites_exit(struct kunit_suite **suites);
 
+void *get_test_case_parameters(struct kunit *test);
+
 /**
  * kunit_test_suites() - used to register one or more &struct kunit_suite
  *			 with KUnit.
diff --git a/lib/kunit/test.c b/lib/kunit/test.c
index c36037200310..c4fd8f729e96 100644
--- a/lib/kunit/test.c
+++ b/lib/kunit/test.c
@@ -236,6 +236,18 @@ void kunit_init_test(struct kunit *test, const char *name, char *log)
 }
 EXPORT_SYMBOL_GPL(kunit_init_test);
 
+void kunit_init_param_test(struct kunit *test, struct kunit_case *test_case)
+{
+	spin_lock_init(&test->lock);
+	INIT_LIST_HEAD(&test->resources);
+	test->parameterized = true;
+	test->param_values = (void *)(test_case->get_params());
+	test->max_parameters_count = test_case->max_parameters_count;
+	test->parameter_size = test_case->parameter_size;
+	test->iterator_count = 0;
+}
+EXPORT_SYMBOL_GPL(kunit_init_param_test);
+
 /*
  * Initializes and runs test case. Does not clean up or do post validations.
  */
@@ -343,6 +355,8 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
 	struct kunit test;
 
 	kunit_init_test(&test, test_case->name, test_case->log);
+	if (test_case->parameterized)
+		kunit_init_param_test(&test, test_case);
 	try_catch = &test.try_catch;
 
 	kunit_try_catch_init(try_catch,
@@ -407,6 +421,19 @@ void __kunit_test_suites_exit(struct kunit_suite **suites)
 }
 EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
 
+/*
+ * Iterator method for the parameterized test cases
+ */
+void *get_test_case_parameters(struct kunit *test)
+{
+	int index = test->iterator_count * test->parameter_size;
+
+	if (test->iterator_count != test->max_parameters_count)
+		test->iterator_count++;
+	return (test->param_values + index);
+}
+EXPORT_SYMBOL_GPL(get_test_case_parameters);
+
 /*
  * Used for static resources and when a kunit_resource * has been created by
  * kunit_alloc_resource().  When an init function is supplied, @data is passed
-- 
2.25.1

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [Linux-kernel-mentees] [RFC v2 2/2] fs: ext4: Modify inode-test.c to use KUnit parameterized testing
  2020-09-30 14:40 [Linux-kernel-mentees] [RFC v2 1/2] kunit: Support for Parameterized Testing Arpitha Raghunandan
@ 2020-10-01  3:21 ` Arpitha Raghunandan
  0 siblings, 0 replies; 2+ messages in thread
From: Arpitha Raghunandan @ 2020-10-01  3:21 UTC (permalink / raw)
  To: brendanhiggins, tytso, adilger.kernel, skhan
  Cc: Arpitha Raghunandan, linux-kernel-mentees, kunit-dev

Modifies fs/ext4/inode-test.c to use the parameterized testing
feature of KUnit.

Signed-off-by: Arpitha Raghunandan <98.arpi@gmail.com>
---
 fs/ext4/inode-test.c | 65 ++++++++++++++++++++++++++------------------
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/fs/ext4/inode-test.c b/fs/ext4/inode-test.c
index d62d802c9c12..f127f9123cc1 100644
--- a/fs/ext4/inode-test.c
+++ b/fs/ext4/inode-test.c
@@ -72,6 +72,8 @@
 #define UPPER_BOUND_NONNEG_EXTRA_BITS_1_CASE\
 	"2446-05-10 Upper bound of 32bit >=0 timestamp. All extra sec bits on"
 
+#define NUMBER_OF_TESTCASES 16
+
 struct timestamp_expectation {
 	const char *test_case_name;
 	struct timespec64 expected;
@@ -101,7 +103,40 @@ static time64_t get_32bit_time(const struct timestamp_expectation * const test)
  */
 static void inode_test_xtimestamp_decoding(struct kunit *test)
 {
-	const struct timestamp_expectation test_data[] = {
+	struct timespec64 timestamp;
+	int i;
+
+	for (i = 0; i < NUMBER_OF_TESTCASES; ++i) {
+		struct timestamp_expectation *test_case = (struct timestamp_expectation *)get_test_case_parameters(test);
+
+		timestamp.tv_sec = get_32bit_time(test_case);
+		ext4_decode_extra_time(&timestamp,
+				       cpu_to_le32(test_case->extra_bits));
+
+		KUNIT_EXPECT_EQ_MSG(test,
+				    test_case->expected.tv_sec,
+				    timestamp.tv_sec,
+				    CASE_NAME_FORMAT,
+				    test_case->test_case_name,
+				    test_case->msb_set,
+				    test_case->lower_bound,
+				    test_case->extra_bits);
+		KUNIT_EXPECT_EQ_MSG(test,
+				    test_case->expected.tv_nsec,
+				    timestamp.tv_nsec,
+				    CASE_NAME_FORMAT,
+				    test_case->test_case_name,
+				    test_case->msb_set,
+				    test_case->lower_bound,
+				    test_case->extra_bits);
+	}
+}
+
+struct timestamp_expectation *get_test_parameters(void)
+{
+	struct timestamp_expectation *test_data = (struct timestamp_expectation *)kmalloc(sizeof(struct timestamp_expectation) * NUMBER_OF_TESTCASES, GFP_KERNEL);
+
+	const struct timestamp_expectation test_data_init[] = {
 		{
 			.test_case_name = LOWER_BOUND_NEG_NO_EXTRA_BITS_CASE,
 			.msb_set = true,
@@ -232,35 +267,13 @@ static void inode_test_xtimestamp_decoding(struct kunit *test)
 		}
 	};
 
-	struct timespec64 timestamp;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(test_data); ++i) {
-		timestamp.tv_sec = get_32bit_time(&test_data[i]);
-		ext4_decode_extra_time(&timestamp,
-				       cpu_to_le32(test_data[i].extra_bits));
+	memcpy(test_data, test_data_init, sizeof(struct timestamp_expectation) * ARRAY_SIZE(test_data_init));
 
-		KUNIT_EXPECT_EQ_MSG(test,
-				    test_data[i].expected.tv_sec,
-				    timestamp.tv_sec,
-				    CASE_NAME_FORMAT,
-				    test_data[i].test_case_name,
-				    test_data[i].msb_set,
-				    test_data[i].lower_bound,
-				    test_data[i].extra_bits);
-		KUNIT_EXPECT_EQ_MSG(test,
-				    test_data[i].expected.tv_nsec,
-				    timestamp.tv_nsec,
-				    CASE_NAME_FORMAT,
-				    test_data[i].test_case_name,
-				    test_data[i].msb_set,
-				    test_data[i].lower_bound,
-				    test_data[i].extra_bits);
-	}
+	return test_data;
 }
 
 static struct kunit_case ext4_inode_test_cases[] = {
-	KUNIT_CASE(inode_test_xtimestamp_decoding),
+	KUNIT_CASE_PARAM(inode_test_xtimestamp_decoding, get_test_parameters, NUMBER_OF_TESTCASES, sizeof(struct timestamp_expectation)),
 	{}
 };
 
-- 
2.25.1

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-10-01  3:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-30 14:40 [Linux-kernel-mentees] [RFC v2 1/2] kunit: Support for Parameterized Testing Arpitha Raghunandan
2020-10-01  3:21 ` [Linux-kernel-mentees] [RFC v2 2/2] fs: ext4: Modify inode-test.c to use KUnit parameterized testing Arpitha Raghunandan

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.