diff mbox series

[2/2] kunit: Allow to filter entries from zero terminated arrays

Message ID 20230926220208.1423-2-michal.wajdeczko@intel.com
State New
Headers show
Series [1/2] kunit: Add param generator macro for zero terminated arrays | expand

Commit Message

Michal Wajdeczko Sept. 26, 2023, 10:02 p.m. UTC
In some cases we may want to generate params based on existing
zero terminated array, but with some entries filtered out.
Extend macro KUNIT_ZERO_ARRAY_PARAM to accept filter function
and provide example how to use it.

$ ./tools/testing/kunit/kunit.py run \
    --kunitconfig ./lib/kunit/.kunitconfig *.example_params*

[ ] Starting KUnit Kernel (1/1)...
[ ] ============================================================
[ ] ========================= example  =========================
[ ] =================== example_params_test  ===================
[ ] [SKIPPED] example value 3
[ ] [PASSED] example value 2
[ ] [PASSED] example value 1
[ ] [SKIPPED] example value 0
[ ] =============== [PASSED] example_params_test ===============
[ ] =================== example_params_test  ===================
[ ] [SKIPPED] example value 3
[ ] [PASSED] example value 2
[ ] [PASSED] example value 1
[ ] =============== [PASSED] example_params_test ===============
[ ] =================== example_params_test  ===================
[ ] [PASSED] example value 2
[ ] [PASSED] example value 1
[ ] =============== [PASSED] example_params_test ===============
[ ] ===================== [PASSED] example =====================
[ ] ============================================================
[ ] Testing complete. Ran 9 tests: passed: 6, skipped: 3

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: David Gow <davidgow@google.com>
Cc: Rae Moar <rmoar@google.com>
---
 include/kunit/test.h           | 19 +++++++++++++++++--
 lib/kunit/kunit-example-test.c |  9 +++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

Comments

Rae Moar Sept. 29, 2023, 7:51 p.m. UTC | #1
On Tue, Sep 26, 2023 at 6:02 PM Michal Wajdeczko
<michal.wajdeczko@intel.com> wrote:
>
> In some cases we may want to generate params based on existing
> zero terminated array, but with some entries filtered out.
> Extend macro KUNIT_ZERO_ARRAY_PARAM to accept filter function
> and provide example how to use it.

Hello!

I definitely understand the use case of wanting to filter params.
However, since this is a static filter, it seems this could be done in
the test file and rather than implemented as a new KUnit feature.

I would be interested to see David's thoughts on this. If we do decide
to implement this as a KUnit feature, I would also prefer if the
filtering ability is available for both the zero-terminated param
arrays and normal param arrays.

Otherwise I just have one comment below. Let me know what you think.

Thanks!
-Rae

>
> $ ./tools/testing/kunit/kunit.py run \
>     --kunitconfig ./lib/kunit/.kunitconfig *.example_params*
>
> [ ] Starting KUnit Kernel (1/1)...
> [ ] ============================================================
> [ ] ========================= example  =========================
> [ ] =================== example_params_test  ===================
> [ ] [SKIPPED] example value 3
> [ ] [PASSED] example value 2
> [ ] [PASSED] example value 1
> [ ] [SKIPPED] example value 0
> [ ] =============== [PASSED] example_params_test ===============
> [ ] =================== example_params_test  ===================
> [ ] [SKIPPED] example value 3
> [ ] [PASSED] example value 2
> [ ] [PASSED] example value 1
> [ ] =============== [PASSED] example_params_test ===============
> [ ] =================== example_params_test  ===================
> [ ] [PASSED] example value 2
> [ ] [PASSED] example value 1
> [ ] =============== [PASSED] example_params_test ===============
> [ ] ===================== [PASSED] example =====================
> [ ] ============================================================
> [ ] Testing complete. Ran 9 tests: passed: 6, skipped: 3
>
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
> Cc: David Gow <davidgow@google.com>
> Cc: Rae Moar <rmoar@google.com>
> ---
>  include/kunit/test.h           | 19 +++++++++++++++++--
>  lib/kunit/kunit-example-test.c |  9 +++++++++
>  2 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/include/kunit/test.h b/include/kunit/test.h
> index 280113ceb6a6..8a87d1ce37e0 100644
> --- a/include/kunit/test.h
> +++ b/include/kunit/test.h
> @@ -1515,20 +1515,24 @@ do {                                                                           \
>         }
>
>  /**
> - * KUNIT_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
> + * KUNIT_FILTERED_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
>   * @name:  prefix for the test parameter generator function.
>   * @array: zero terminated array of test parameters.
>   * @get_desc: function to convert param to description; NULL to use default
> + * @filter: function to filter out unwanted params (like duplicates); can be NULL
>   *
>   * Define function @name_gen_params which uses zero terminated @array to generate parameters.
>   */
> -#define KUNIT_ZERO_ARRAY_PARAM(name, array, get_desc)                                          \
> +#define KUNIT_FILTERED_ZERO_ARRAY_PARAM(name, array, get_desc, filter)                         \
>         static const void *name##_gen_params(const void *prev, char *desc)                      \
>         {                                                                                       \
>                 typeof((array)[0]) *__prev = prev;                                              \
>                 typeof(__prev) __next = __prev ? __prev + 1 : (array);                          \
>                 void (*__get_desc)(typeof(__next), char *) = get_desc;                          \
> +               bool (*__filter)(typeof(__prev), typeof(__next)) = filter;                      \
>                 for (; memchr_inv(__next, 0, sizeof(*__next)); __prev = __next++) {             \
> +                       if (__filter && !__filter(__prev, __next))                              \
> +                               continue;                                                       \
>                         if (__get_desc)                                                         \
>                                 __get_desc(__next, desc);                                       \
>                         return __next;                                                          \
> @@ -1536,6 +1540,17 @@ do {                                                                            \
>                 return NULL;                                                                    \
>         }
>
> +/**
> + * KUNIT_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
> + * @name:  prefix for the test parameter generator function.
> + * @array: zero terminated array of test parameters.
> + * @get_desc: function to convert param to description; NULL to use default
> + *
> + * Define function @name_gen_params which uses zero terminated @array to generate parameters.
> + */
> +#define KUNIT_ZERO_ARRAY_PARAM(name, array, get_desc)  \
> +       KUNIT_FILTERED_ZERO_ARRAY_PARAM(name, array, get_desc, NULL)
> +
>  // TODO(dlatypov@google.com): consider eventually migrating users to explicitly
>  // include resource.h themselves if they need it.
>  #include <kunit/resource.h>
> diff --git a/lib/kunit/kunit-example-test.c b/lib/kunit/kunit-example-test.c
> index ad9ebcfd513e..a3268754392c 100644
> --- a/lib/kunit/kunit-example-test.c
> +++ b/lib/kunit/kunit-example-test.c
> @@ -201,8 +201,16 @@ static void example_param_get_desc(const struct example_param *p, char *desc)
>         snprintf(desc, KUNIT_PARAM_DESC_SIZE, "example value %d", p->value);
>  }
>
> +static bool example_param_filter(const struct example_param *prev,
> +                                const struct example_param *next)
> +{
> +       return next->value < 3;
> +}
> +
>  KUNIT_ARRAY_PARAM(example, example_params_array, example_param_get_desc);
>  KUNIT_ZERO_ARRAY_PARAM(example_zero, example_params_array, example_param_get_desc);
> +KUNIT_FILTERED_ZERO_ARRAY_PARAM(example_filter, example_params_array, example_param_get_desc,
> +                               example_param_filter);
>
>  /*
>   * This test shows the use of params.
> @@ -248,6 +256,7 @@ static struct kunit_case example_test_cases[] = {
>         KUNIT_CASE(example_static_stub_test),
>         KUNIT_CASE_PARAM(example_params_test, example_gen_params),
>         KUNIT_CASE_PARAM(example_params_test, example_zero_gen_params),
> +       KUNIT_CASE_PARAM(example_params_test, example_filter_gen_params),

Similar to last patch, I would probably prefer the test names to
differ slightly for the three param tests.

>         KUNIT_CASE_SLOW(example_slow_test),
>         {}
>  };
> --
> 2.25.1
>
> --
> You received this message because you are subscribed to the Google Groups "KUnit Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to kunit-dev+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/kunit-dev/20230926220208.1423-2-michal.wajdeczko%40intel.com.
David Gow Sept. 30, 2023, 8:58 a.m. UTC | #2
On Wed, 27 Sept 2023 at 06:02, Michal Wajdeczko
<michal.wajdeczko@intel.com> wrote:
>
> In some cases we may want to generate params based on existing
> zero terminated array, but with some entries filtered out.
> Extend macro KUNIT_ZERO_ARRAY_PARAM to accept filter function
> and provide example how to use it.
>
> $ ./tools/testing/kunit/kunit.py run \
>     --kunitconfig ./lib/kunit/.kunitconfig *.example_params*
>
> [ ] Starting KUnit Kernel (1/1)...
> [ ] ============================================================
> [ ] ========================= example  =========================
> [ ] =================== example_params_test  ===================
> [ ] [SKIPPED] example value 3
> [ ] [PASSED] example value 2
> [ ] [PASSED] example value 1
> [ ] [SKIPPED] example value 0
> [ ] =============== [PASSED] example_params_test ===============
> [ ] =================== example_params_test  ===================
> [ ] [SKIPPED] example value 3
> [ ] [PASSED] example value 2
> [ ] [PASSED] example value 1
> [ ] =============== [PASSED] example_params_test ===============
> [ ] =================== example_params_test  ===================
> [ ] [PASSED] example value 2
> [ ] [PASSED] example value 1
> [ ] =============== [PASSED] example_params_test ===============
> [ ] ===================== [PASSED] example =====================
> [ ] ============================================================
> [ ] Testing complete. Ran 9 tests: passed: 6, skipped: 3
>
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
> Cc: David Gow <davidgow@google.com>
> Cc: Rae Moar <rmoar@google.com>
> ---

I tend to agree with Rae here that this is:
a) starting to get quite specific, and might be better served by a
per-test generator function than a generic helper here, and
b) probably would need to be implemented for both  ZERO_ARRAY_PARAM
and the regular ARRAY_PARAM, for consistency's sake.

I'd probably err on the side of letting tests implement something like
this themselves, and then reconsider a helper macro once there are
several tests all using the same thing. If, for example, all the users
of this are just checking PCI ids, or something, it may make more
sense to just have a PCI-specific macro they can share.

Regardless, I'd love to see a real-world example of this being used,
which may make it seem less niche.

Thanks,
-- David

>  include/kunit/test.h           | 19 +++++++++++++++++--
>  lib/kunit/kunit-example-test.c |  9 +++++++++
>  2 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/include/kunit/test.h b/include/kunit/test.h
> index 280113ceb6a6..8a87d1ce37e0 100644
> --- a/include/kunit/test.h
> +++ b/include/kunit/test.h
> @@ -1515,20 +1515,24 @@ do {                                                                           \
>         }
>
>  /**
> - * KUNIT_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
> + * KUNIT_FILTERED_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
>   * @name:  prefix for the test parameter generator function.
>   * @array: zero terminated array of test parameters.
>   * @get_desc: function to convert param to description; NULL to use default
> + * @filter: function to filter out unwanted params (like duplicates); can be NULL
>   *
>   * Define function @name_gen_params which uses zero terminated @array to generate parameters.
>   */
> -#define KUNIT_ZERO_ARRAY_PARAM(name, array, get_desc)                                          \
> +#define KUNIT_FILTERED_ZERO_ARRAY_PARAM(name, array, get_desc, filter)                         \
>         static const void *name##_gen_params(const void *prev, char *desc)                      \
>         {                                                                                       \
>                 typeof((array)[0]) *__prev = prev;                                              \
>                 typeof(__prev) __next = __prev ? __prev + 1 : (array);                          \
>                 void (*__get_desc)(typeof(__next), char *) = get_desc;                          \
> +               bool (*__filter)(typeof(__prev), typeof(__next)) = filter;                      \
>                 for (; memchr_inv(__next, 0, sizeof(*__next)); __prev = __next++) {             \
> +                       if (__filter && !__filter(__prev, __next))                              \
> +                               continue;                                                       \
>                         if (__get_desc)                                                         \
>                                 __get_desc(__next, desc);                                       \
>                         return __next;                                                          \
> @@ -1536,6 +1540,17 @@ do {                                                                            \
>                 return NULL;                                                                    \
>         }
>
> +/**
> + * KUNIT_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
> + * @name:  prefix for the test parameter generator function.
> + * @array: zero terminated array of test parameters.
> + * @get_desc: function to convert param to description; NULL to use default
> + *
> + * Define function @name_gen_params which uses zero terminated @array to generate parameters.
> + */
> +#define KUNIT_ZERO_ARRAY_PARAM(name, array, get_desc)  \
> +       KUNIT_FILTERED_ZERO_ARRAY_PARAM(name, array, get_desc, NULL)
> +
>  // TODO(dlatypov@google.com): consider eventually migrating users to explicitly
>  // include resource.h themselves if they need it.
>  #include <kunit/resource.h>
> diff --git a/lib/kunit/kunit-example-test.c b/lib/kunit/kunit-example-test.c
> index ad9ebcfd513e..a3268754392c 100644
> --- a/lib/kunit/kunit-example-test.c
> +++ b/lib/kunit/kunit-example-test.c
> @@ -201,8 +201,16 @@ static void example_param_get_desc(const struct example_param *p, char *desc)
>         snprintf(desc, KUNIT_PARAM_DESC_SIZE, "example value %d", p->value);
>  }
>
> +static bool example_param_filter(const struct example_param *prev,
> +                                const struct example_param *next)
> +{
> +       return next->value < 3;
> +}
> +
>  KUNIT_ARRAY_PARAM(example, example_params_array, example_param_get_desc);
>  KUNIT_ZERO_ARRAY_PARAM(example_zero, example_params_array, example_param_get_desc);
> +KUNIT_FILTERED_ZERO_ARRAY_PARAM(example_filter, example_params_array, example_param_get_desc,
> +                               example_param_filter);

I think we'd probably want some more comments around these examples,
just to make it a little clearer what the difference between these
features are and what results we should expect. The purpose the the
'example_test' is basically documentation, so I think we'll want to
either make this a clearer example of how/why you'd want to use this,
or leave it out of the examples (and just document it in the
documentation, and possibly test it in another kunit test).


>
>  /*
>   * This test shows the use of params.
> @@ -248,6 +256,7 @@ static struct kunit_case example_test_cases[] = {
>         KUNIT_CASE(example_static_stub_test),
>         KUNIT_CASE_PARAM(example_params_test, example_gen_params),
>         KUNIT_CASE_PARAM(example_params_test, example_zero_gen_params),
> +       KUNIT_CASE_PARAM(example_params_test, example_filter_gen_params),
>         KUNIT_CASE_SLOW(example_slow_test),
>         {}
>  };
> --
> 2.25.1
>
> --
> You received this message because you are subscribed to the Google Groups "KUnit Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to kunit-dev+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/kunit-dev/20230926220208.1423-2-michal.wajdeczko%40intel.com.
diff mbox series

Patch

diff --git a/include/kunit/test.h b/include/kunit/test.h
index 280113ceb6a6..8a87d1ce37e0 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -1515,20 +1515,24 @@  do {									       \
 	}
 
 /**
- * KUNIT_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
+ * KUNIT_FILTERED_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
  * @name:  prefix for the test parameter generator function.
  * @array: zero terminated array of test parameters.
  * @get_desc: function to convert param to description; NULL to use default
+ * @filter: function to filter out unwanted params (like duplicates); can be NULL
  *
  * Define function @name_gen_params which uses zero terminated @array to generate parameters.
  */
-#define KUNIT_ZERO_ARRAY_PARAM(name, array, get_desc)						\
+#define KUNIT_FILTERED_ZERO_ARRAY_PARAM(name, array, get_desc, filter)				\
 	static const void *name##_gen_params(const void *prev, char *desc)			\
 	{											\
 		typeof((array)[0]) *__prev = prev;						\
 		typeof(__prev) __next = __prev ? __prev + 1 : (array);				\
 		void (*__get_desc)(typeof(__next), char *) = get_desc;				\
+		bool (*__filter)(typeof(__prev), typeof(__next)) = filter;			\
 		for (; memchr_inv(__next, 0, sizeof(*__next)); __prev = __next++) {		\
+			if (__filter && !__filter(__prev, __next))				\
+				continue;							\
 			if (__get_desc)								\
 				__get_desc(__next, desc);					\
 			return __next;								\
@@ -1536,6 +1540,17 @@  do {									       \
 		return NULL;									\
 	}
 
+/**
+ * KUNIT_ZERO_ARRAY_PARAM() - Define test parameter generator from a zero terminated array.
+ * @name:  prefix for the test parameter generator function.
+ * @array: zero terminated array of test parameters.
+ * @get_desc: function to convert param to description; NULL to use default
+ *
+ * Define function @name_gen_params which uses zero terminated @array to generate parameters.
+ */
+#define KUNIT_ZERO_ARRAY_PARAM(name, array, get_desc)	\
+	KUNIT_FILTERED_ZERO_ARRAY_PARAM(name, array, get_desc, NULL)
+
 // TODO(dlatypov@google.com): consider eventually migrating users to explicitly
 // include resource.h themselves if they need it.
 #include <kunit/resource.h>
diff --git a/lib/kunit/kunit-example-test.c b/lib/kunit/kunit-example-test.c
index ad9ebcfd513e..a3268754392c 100644
--- a/lib/kunit/kunit-example-test.c
+++ b/lib/kunit/kunit-example-test.c
@@ -201,8 +201,16 @@  static void example_param_get_desc(const struct example_param *p, char *desc)
 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "example value %d", p->value);
 }
 
+static bool example_param_filter(const struct example_param *prev,
+				 const struct example_param *next)
+{
+	return next->value < 3;
+}
+
 KUNIT_ARRAY_PARAM(example, example_params_array, example_param_get_desc);
 KUNIT_ZERO_ARRAY_PARAM(example_zero, example_params_array, example_param_get_desc);
+KUNIT_FILTERED_ZERO_ARRAY_PARAM(example_filter, example_params_array, example_param_get_desc,
+				example_param_filter);
 
 /*
  * This test shows the use of params.
@@ -248,6 +256,7 @@  static struct kunit_case example_test_cases[] = {
 	KUNIT_CASE(example_static_stub_test),
 	KUNIT_CASE_PARAM(example_params_test, example_gen_params),
 	KUNIT_CASE_PARAM(example_params_test, example_zero_gen_params),
+	KUNIT_CASE_PARAM(example_params_test, example_filter_gen_params),
 	KUNIT_CASE_SLOW(example_slow_test),
 	{}
 };