diff mbox series

[v8,07/10] lib: add basic KUnit test for lib/math

Message ID 20240517173607.800549-1-devarsht@ti.com (mailing list archive)
State New, archived
Headers show
Series Add V4L2 M2M Driver for E5010 JPEG Encoder | expand

Commit Message

Devarsh Thakkar May 17, 2024, 5:36 p.m. UTC
From: Daniel Latypov <dlatypov@google.com>

Add basic test coverage for files that don't require any config options:
* part of math.h (what seem to be the most commonly used macros)
* gcd.c
* lcm.c
* int_sqrt.c
* reciprocal_div.c
(Ignored int_pow.c since it's a simple textbook algorithm.)

These tests aren't particularly interesting, but they
* provide short and simple examples of parameterized tests
* provide a place to add tests for any new files in this dir
* are written so adding new test cases to cover edge cases should be
  easy
  * looking at code coverage, we hit all the branches in the .c files

Signed-off-by: Daniel Latypov <dlatypov@google.com>
Reviewed-by: David Gow <davidgow@google.com>
[devarsht: Rebase to 6.9 and change license to GPL]
Signed-off-by: Devarsh Thakkar <devarsht@ti.com>
---
Changes since v6:
* Rebase to linux-next, change license to GPL as suggested by checkpatch.

Changes since v5:
* add in test cases for roundup/rounddown
* address misc comments from David

Changes since v4:
* add in test cases for some math.h macros (abs, round_up/round_down,
  div_round_down/closest)
* use parameterized testing less to keep things terser

Changes since v3:
* fix `checkpatch.pl --strict` warnings
* add test cases for gcd(0,0) and lcm(0,0)
* minor: don't test both gcd(a,b) and gcd(b,a) when a == b

Changes since v2: mv math_test.c => math_kunit.c

Changes since v1:
* Rebase and rewrite to use the new parameterized testing support.
* misc: fix overflow in literal and inline int_sqrt format string.
* related: commit 1f0e943df68a ("Documentation: kunit: provide guidance
for testing many inputs") was merged explaining the patterns shown here.
  * there's an in-flight patch to update it for parameterized testing.
---
 lib/math/Kconfig      |  11 ++
 lib/math/Makefile     |   1 +
 lib/math/math_kunit.c | 291 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 303 insertions(+)
 create mode 100644 lib/math/math_kunit.c

Comments

Andy Shevchenko May 17, 2024, 8:14 p.m. UTC | #1
On Fri, May 17, 2024 at 11:06:07PM +0530, Devarsh Thakkar wrote:
> From: Daniel Latypov <dlatypov@google.com>
> 
> Add basic test coverage for files that don't require any config options:
> * part of math.h (what seem to be the most commonly used macros)
> * gcd.c
> * lcm.c
> * int_sqrt.c
> * reciprocal_div.c
> (Ignored int_pow.c since it's a simple textbook algorithm.)
> 
> These tests aren't particularly interesting, but they
> * provide short and simple examples of parameterized tests
> * provide a place to add tests for any new files in this dir
> * are written so adding new test cases to cover edge cases should be
>   easy
>   * looking at code coverage, we hit all the branches in the .c files

...

> [devarsht: Rebase to 6.9 and change license to GPL]

I'm not sure that you may change license. It needs the author's confirmation.

> ---
> Changes since v6:
> * Rebase to linux-next, change license to GPL as suggested by checkpatch.

Note, checkpatch.pl is not false positives free. Be careful
with what it suggests.

> +#include <kunit/test.h>
> +#include <linux/gcd.h>

> +#include <linux/kernel.h>

Do you know why this header is included?

> +#include <linux/lcm.h>

+ math.h // obviously
+ module.h

> +#include <linux/reciprocal_div.h>

+ types.h

...

Other than above, LGTM.
Daniel Latypov May 17, 2024, 8:53 p.m. UTC | #2
On Fri, May 17, 2024 at 1:14 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> > [devarsht: Rebase to 6.9 and change license to GPL]
>
> I'm not sure that you may change license. It needs the author's confirmation.

Checking, this is referring to the MODULE_LICENSE, which used to be
MODULE_LICENSE("GPL v2");

and is now
MODULE_LICENSE("GPL");

If checkpatch is suggesting that now, then changing it sounds good to me.

>
> > ---
> > Changes since v6:
> > * Rebase to linux-next, change license to GPL as suggested by checkpatch.
>
> Note, checkpatch.pl is not false positives free. Be careful
> with what it suggests.
>
> > +#include <kunit/test.h>
> > +#include <linux/gcd.h>
>
> > +#include <linux/kernel.h>
>
> Do you know why this header is included?

I think I had put it in the original before a lot of the work you did
to split things out of kernel.h.
I haven't had time to look apply this patch series locally yet, but
I'd be pretty sure we can remove it without anything breaking.

Thanks,
Daniel
Andy Shevchenko May 20, 2024, 9:26 a.m. UTC | #3
On Fri, May 17, 2024 at 01:53:47PM -0700, Daniel Latypov wrote:
> On Fri, May 17, 2024 at 1:14 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:

...

> > > [devarsht: Rebase to 6.9 and change license to GPL]
> >
> > I'm not sure that you may change license. It needs the author's confirmation.
> 
> Checking, this is referring to the MODULE_LICENSE, which used to be
> MODULE_LICENSE("GPL v2");
> 
> and is now
> MODULE_LICENSE("GPL");
> 
> If checkpatch is suggesting that now, then changing it sounds good to me.

In this case I agree on the change as it's purely syntax and not semantic.

> > > ---
> > > Changes since v6:
> > > * Rebase to linux-next, change license to GPL as suggested by checkpatch.
> >
> > Note, checkpatch.pl is not false positives free. Be careful
> > with what it suggests.
> >
> > > +#include <kunit/test.h>
> > > +#include <linux/gcd.h>
> >
> > > +#include <linux/kernel.h>
> >
> > Do you know why this header is included?
> 
> I think I had put it in the original before a lot of the work you did
> to split things out of kernel.h.
> I haven't had time to look apply this patch series locally yet, but
> I'd be pretty sure we can remove it without anything breaking.

Briefly looking at the code I even not sure it was needed before, but maybe
I missed something, in any case, please remove / replace it.
Devarsh Thakkar May 20, 2024, 11:41 a.m. UTC | #4
Hi Andy, Daniel,

On 18/05/24 01:44, Andy Shevchenko wrote:
> On Fri, May 17, 2024 at 11:06:07PM +0530, Devarsh Thakkar wrote:
[..]
> 
>> [devarsht: Rebase to 6.9 and change license to GPL]
> 
> I'm not sure that you may change license. It needs the author's confirmation.
> 

As per latest licensing doc [1], It quotes that GPL  is same as GPL v2 and GPL
v2 exists only for historical reasons as shared below :

“GPL v2 Same as “GPL”. It exists for historic reasons."

So I think it should be fine and more apt to use GPL. This is also highlighted
in below commit:
bf7fbeeae6db644ef5995085de2bc5c6121f8c8d module: Cure the MODULE_LICENSE "GPL"
vs. "GPL v2" bogosity

>> ---
>> Changes since v6:
>> * Rebase to linux-next, change license to GPL as suggested by checkpatch.
> 
> Note, checkpatch.pl is not false positives free. Be careful
> with what it suggests.
> 
>> +#include <kunit/test.h>
>> +#include <linux/gcd.h>
> 
>> +#include <linux/kernel.h>
> 
> Do you know why this header is included?
> 

It includes all the other required headers (including those you mentioned
below), and header list is probably copied from other files in same directory.
But it does suffice the requirements as I have verified the compilation.

>> +#include <linux/lcm.h>
> 
> + math.h // obviously
> + module.h
> 
>> +#include <linux/reciprocal_div.h>
> 
> + types.h
> 

All the above headers are already included as part of kernel.h

Kindly let me know if any queries.

[1]: https://docs.kernel.org/process/license-rules.html

Regards
Devarsh
Andy Shevchenko May 20, 2024, 12:22 p.m. UTC | #5
On Mon, May 20, 2024 at 05:11:18PM +0530, Devarsh Thakkar wrote:
> On 18/05/24 01:44, Andy Shevchenko wrote:
> > On Fri, May 17, 2024 at 11:06:07PM +0530, Devarsh Thakkar wrote:

[..]

> >> +#include <kunit/test.h>
> >> +#include <linux/gcd.h>
> > 
> >> +#include <linux/kernel.h>
> > 
> > Do you know why this header is included?
> 
> It includes all the other required headers (including those you mentioned
> below), and header list is probably copied from other files in same directory.
> But it does suffice the requirements as I have verified the compilation.

Yes, and one should follow IWYU principle and not cargo cult or whatever
arbitrary lists.

> >> +#include <linux/lcm.h>
> > 
> > + math.h // obviously
> > + module.h
> > 
> >> +#include <linux/reciprocal_div.h>
> > 
> > + types.h
> 
> All the above headers are already included as part of kernel.h

Yes, that's why you should not use "proxy" headers.
Have you read the top comment in the kernel.h?
Devarsh Thakkar May 20, 2024, 2:21 p.m. UTC | #6
On 20/05/24 17:52, Andy Shevchenko wrote:
> On Mon, May 20, 2024 at 05:11:18PM +0530, Devarsh Thakkar wrote:
>> On 18/05/24 01:44, Andy Shevchenko wrote:
>>> On Fri, May 17, 2024 at 11:06:07PM +0530, Devarsh Thakkar wrote:
> 
> [..]
> 

[..]
> Yes, and one should follow IWYU principle and not cargo cult or whatever
> arbitrary lists.
> 

Agreed.

>>>> +#include <linux/lcm.h>
>>>
>>> + math.h // obviously
>>> + module.h
>>>
>>>> +#include <linux/reciprocal_div.h>
>>>
>>> + types.h
>>
>> All the above headers are already included as part of kernel.h
> 
> Yes, that's why you should not use "proxy" headers.
> Have you read the top comment in the kernel.h?
> 

Yes, it says it is not recommended to include this inside another header file.
Although here we are adding it inside c file, but I can still try avoid it and
include only the required headers instead of kernel.h as you recommended.

Regards
Devarsh
Andy Shevchenko May 20, 2024, 2:35 p.m. UTC | #7
On Mon, May 20, 2024 at 07:51:24PM +0530, Devarsh Thakkar wrote:
> On 20/05/24 17:52, Andy Shevchenko wrote:
> > On Mon, May 20, 2024 at 05:11:18PM +0530, Devarsh Thakkar wrote:
> >> On 18/05/24 01:44, Andy Shevchenko wrote:
> >>> On Fri, May 17, 2024 at 11:06:07PM +0530, Devarsh Thakkar wrote:

[..]

> > Yes, and one should follow IWYU principle and not cargo cult or whatever
> > arbitrary lists.
> 
> Agreed.

> >>>> +#include <linux/lcm.h>
> >>>
> >>> + math.h // obviously
> >>> + module.h
> >>>
> >>>> +#include <linux/reciprocal_div.h>
> >>>
> >>> + types.h
> >>
> >> All the above headers are already included as part of kernel.h
> > 
> > Yes, that's why you should not use "proxy" headers.
> > Have you read the top comment in the kernel.h?
> 
> Yes, it says it is not recommended to include this inside another header file.
> Although here we are adding it inside c file, but I can still try avoid it and
> include only the required headers instead of kernel.h as you recommended.

Right, but the first sentence there is
"This header has combined a lot of unrelated to each other stuff."

Can you explain how you use in your code all that unrelated stuff?
For example, how do you use *trace_*() calls? Or maybe might_*() calls?
or anything else that is directly provided by kernel.h?

Besides IWYU principle above, it's good to have a justification for each
inclusion the C file has. I believe there is no a such in _this_ case.
diff mbox series

Patch

diff --git a/lib/math/Kconfig b/lib/math/Kconfig
index 0634b428d0cb..832c6989ca13 100644
--- a/lib/math/Kconfig
+++ b/lib/math/Kconfig
@@ -15,3 +15,14 @@  config PRIME_NUMBERS
 
 config RATIONAL
 	tristate
+
+config MATH_KUNIT_TEST
+	tristate "KUnit test for math helper functions"
+	help
+	  This builds unit test for math helper functions as defined in lib/math
+	  and math.h.
+
+	  For more information on KUNIT and unit tests in general, please refer
+	  to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+	  If unsure, say N.
diff --git a/lib/math/Makefile b/lib/math/Makefile
index 91fcdb0c9efe..dcf65d10dab2 100644
--- a/lib/math/Makefile
+++ b/lib/math/Makefile
@@ -7,3 +7,4 @@  obj-$(CONFIG_RATIONAL)		+= rational.o
 
 obj-$(CONFIG_TEST_DIV64)	+= test_div64.o
 obj-$(CONFIG_RATIONAL_KUNIT_TEST) += rational-test.o
+obj-$(CONFIG_MATH_KUNIT_TEST) += math_kunit.o
diff --git a/lib/math/math_kunit.c b/lib/math/math_kunit.c
new file mode 100644
index 000000000000..1b00e4195a1a
--- /dev/null
+++ b/lib/math/math_kunit.c
@@ -0,0 +1,291 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Simple KUnit suite for math helper funcs that are always enabled.
+ *
+ * Copyright (C) 2020, Google LLC.
+ * Author: Daniel Latypov <dlatypov@google.com>
+ */
+
+#include <kunit/test.h>
+#include <linux/gcd.h>
+#include <linux/kernel.h>
+#include <linux/lcm.h>
+#include <linux/reciprocal_div.h>
+
+static void abs_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, abs((char)0), (char)0);
+	KUNIT_EXPECT_EQ(test, abs((char)42), (char)42);
+	KUNIT_EXPECT_EQ(test, abs((char)-42), (char)42);
+
+	/* The expression in the macro is actually promoted to an int. */
+	KUNIT_EXPECT_EQ(test, abs((short)0),  0);
+	KUNIT_EXPECT_EQ(test, abs((short)42),  42);
+	KUNIT_EXPECT_EQ(test, abs((short)-42),  42);
+
+	KUNIT_EXPECT_EQ(test, abs(0),  0);
+	KUNIT_EXPECT_EQ(test, abs(42),  42);
+	KUNIT_EXPECT_EQ(test, abs(-42),  42);
+
+	KUNIT_EXPECT_EQ(test, abs(0L), 0L);
+	KUNIT_EXPECT_EQ(test, abs(42L), 42L);
+	KUNIT_EXPECT_EQ(test, abs(-42L), 42L);
+
+	KUNIT_EXPECT_EQ(test, abs(0LL), 0LL);
+	KUNIT_EXPECT_EQ(test, abs(42LL), 42LL);
+	KUNIT_EXPECT_EQ(test, abs(-42LL), 42LL);
+
+	/* Unsigned types get casted to signed. */
+	KUNIT_EXPECT_EQ(test, abs(0ULL), 0LL);
+	KUNIT_EXPECT_EQ(test, abs(42ULL), 42LL);
+}
+
+static void int_sqrt_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, int_sqrt(0UL), 0UL);
+	KUNIT_EXPECT_EQ(test, int_sqrt(1UL), 1UL);
+	KUNIT_EXPECT_EQ(test, int_sqrt(4UL), 2UL);
+	KUNIT_EXPECT_EQ(test, int_sqrt(5UL), 2UL);
+	KUNIT_EXPECT_EQ(test, int_sqrt(8UL), 2UL);
+	KUNIT_EXPECT_EQ(test, int_sqrt(1UL << 30), 1UL << 15);
+}
+
+static void round_up_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, round_up(0, 1), 0);
+	KUNIT_EXPECT_EQ(test, round_up(1, 2), 2);
+	KUNIT_EXPECT_EQ(test, round_up(3, 2), 4);
+	KUNIT_EXPECT_EQ(test, round_up((1 << 30) - 1, 2), 1 << 30);
+	KUNIT_EXPECT_EQ(test, round_up((1 << 30) - 1, 1 << 29), 1 << 30);
+}
+
+static void round_down_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, round_down(0, 1), 0);
+	KUNIT_EXPECT_EQ(test, round_down(1, 2), 0);
+	KUNIT_EXPECT_EQ(test, round_down(3, 2), 2);
+	KUNIT_EXPECT_EQ(test, round_down((1 << 30) - 1, 2), (1 << 30) - 2);
+	KUNIT_EXPECT_EQ(test, round_down((1 << 30) - 1, 1 << 29), 1 << 29);
+}
+
+/* These versions can round to numbers that aren't a power of two */
+static void roundup_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, roundup(0, 1), 0);
+	KUNIT_EXPECT_EQ(test, roundup(1, 2), 2);
+	KUNIT_EXPECT_EQ(test, roundup(3, 2), 4);
+	KUNIT_EXPECT_EQ(test, roundup((1 << 30) - 1, 2), 1 << 30);
+	KUNIT_EXPECT_EQ(test, roundup((1 << 30) - 1, 1 << 29), 1 << 30);
+
+	KUNIT_EXPECT_EQ(test, roundup(3, 2), 4);
+	KUNIT_EXPECT_EQ(test, roundup(4, 3), 6);
+}
+
+static void rounddown_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, rounddown(0, 1), 0);
+	KUNIT_EXPECT_EQ(test, rounddown(1, 2), 0);
+	KUNIT_EXPECT_EQ(test, rounddown(3, 2), 2);
+	KUNIT_EXPECT_EQ(test, rounddown((1 << 30) - 1, 2), (1 << 30) - 2);
+	KUNIT_EXPECT_EQ(test, rounddown((1 << 30) - 1, 1 << 29), 1 << 29);
+
+	KUNIT_EXPECT_EQ(test, rounddown(3, 2), 2);
+	KUNIT_EXPECT_EQ(test, rounddown(4, 3), 3);
+}
+
+static void div_round_up_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_UP(0, 1), 0);
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_UP(20, 10), 2);
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_UP(21, 10), 3);
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_UP(21, 20), 2);
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_UP(21, 99), 1);
+}
+
+static void div_round_closest_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_CLOSEST(0, 1), 0);
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_CLOSEST(20, 10), 2);
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_CLOSEST(21, 10), 2);
+	KUNIT_EXPECT_EQ(test, DIV_ROUND_CLOSEST(25, 10), 3);
+}
+
+/* Generic test case for unsigned long inputs. */
+struct test_case {
+	unsigned long a, b;
+	unsigned long result;
+};
+
+static struct test_case gcd_cases[] = {
+	{
+		.a = 0, .b = 0,
+		.result = 0,
+	},
+	{
+		.a = 0, .b = 1,
+		.result = 1,
+	},
+	{
+		.a = 2, .b = 2,
+		.result = 2,
+	},
+	{
+		.a = 2, .b = 4,
+		.result = 2,
+	},
+	{
+		.a = 3, .b = 5,
+		.result = 1,
+	},
+	{
+		.a = 3 * 9, .b = 3 * 5,
+		.result = 3,
+	},
+	{
+		.a = 3 * 5 * 7, .b = 3 * 5 * 11,
+		.result = 15,
+	},
+	{
+		.a = 1 << 21,
+		.b = (1 << 21) - 1,
+		.result = 1,
+	},
+};
+
+KUNIT_ARRAY_PARAM(gcd, gcd_cases, NULL);
+
+static void gcd_test(struct kunit *test)
+{
+	const char *message_fmt = "gcd(%lu, %lu)";
+	const struct test_case *test_param = test->param_value;
+
+	KUNIT_EXPECT_EQ_MSG(test, test_param->result,
+			    gcd(test_param->a, test_param->b),
+			    message_fmt, test_param->a,
+			    test_param->b);
+
+	if (test_param->a == test_param->b)
+		return;
+
+	/* gcd(a,b) == gcd(b,a) */
+	KUNIT_EXPECT_EQ_MSG(test, test_param->result,
+			    gcd(test_param->b, test_param->a),
+			    message_fmt, test_param->b,
+			    test_param->a);
+}
+
+static struct test_case lcm_cases[] = {
+	{
+		.a = 0, .b = 0,
+		.result = 0,
+	},
+	{
+		.a = 0, .b = 1,
+		.result = 0,
+	},
+	{
+		.a = 1, .b = 2,
+		.result = 2,
+	},
+	{
+		.a = 2, .b = 2,
+		.result = 2,
+	},
+	{
+		.a = 3 * 5, .b = 3 * 7,
+		.result = 3 * 5 * 7,
+	},
+};
+
+KUNIT_ARRAY_PARAM(lcm, lcm_cases, NULL);
+
+static void lcm_test(struct kunit *test)
+{
+	const char *message_fmt = "lcm(%lu, %lu)";
+	const struct test_case *test_param = test->param_value;
+
+	KUNIT_EXPECT_EQ_MSG(test, test_param->result,
+			    lcm(test_param->a, test_param->b),
+			    message_fmt, test_param->a,
+			    test_param->b);
+
+	if (test_param->a == test_param->b)
+		return;
+
+	/* lcm(a,b) == lcm(b,a) */
+	KUNIT_EXPECT_EQ_MSG(test, test_param->result,
+			    lcm(test_param->b, test_param->a),
+			    message_fmt, test_param->b,
+			    test_param->a);
+}
+
+struct u32_test_case {
+	u32 a, b;
+	u32 result;
+};
+
+static struct u32_test_case reciprocal_div_cases[] = {
+	{
+		.a = 0, .b = 1,
+		.result = 0,
+	},
+	{
+		.a = 42, .b = 20,
+		.result = 2,
+	},
+	{
+		.a = 42, .b = 9999,
+		.result = 0,
+	},
+	{
+		.a = (1 << 16), .b = (1 << 14),
+		.result = 1 << 2,
+	},
+};
+
+KUNIT_ARRAY_PARAM(reciprocal_div, reciprocal_div_cases, NULL);
+
+static void reciprocal_div_test(struct kunit *test)
+{
+	const struct u32_test_case *test_param = test->param_value;
+	struct reciprocal_value rv = reciprocal_value(test_param->b);
+
+	KUNIT_EXPECT_EQ_MSG(test, test_param->result,
+			    reciprocal_divide(test_param->a, rv),
+			    "reciprocal_divide(%u, %u)",
+			    test_param->a, test_param->b);
+}
+
+static void reciprocal_scale_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, reciprocal_scale(0u, 100), 0u);
+	KUNIT_EXPECT_EQ(test, reciprocal_scale(1u, 100), 0u);
+	KUNIT_EXPECT_EQ(test, reciprocal_scale(1u << 4, 1 << 28), 1u);
+	KUNIT_EXPECT_EQ(test, reciprocal_scale(1u << 16, 1 << 28), 1u << 12);
+	KUNIT_EXPECT_EQ(test, reciprocal_scale(~0u, 1 << 28), (1u << 28) - 1);
+}
+
+static struct kunit_case math_test_cases[] = {
+	KUNIT_CASE(abs_test),
+	KUNIT_CASE(int_sqrt_test),
+	KUNIT_CASE(round_up_test),
+	KUNIT_CASE(round_down_test),
+	KUNIT_CASE(roundup_test),
+	KUNIT_CASE(rounddown_test),
+	KUNIT_CASE(div_round_up_test),
+	KUNIT_CASE(div_round_closest_test),
+	KUNIT_CASE_PARAM(gcd_test, gcd_gen_params),
+	KUNIT_CASE_PARAM(lcm_test, lcm_gen_params),
+	KUNIT_CASE_PARAM(reciprocal_div_test, reciprocal_div_gen_params),
+	KUNIT_CASE(reciprocal_scale_test),
+	{}
+};
+
+static struct kunit_suite math_test_suite = {
+	.name = "lib-math",
+	.test_cases = math_test_cases,
+};
+
+kunit_test_suites(&math_test_suite);
+
+MODULE_LICENSE("GPL");