All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brendan Higgins <brendanhiggins@google.com>
To: Alan Maguire <alan.maguire@oracle.com>
Cc: Patricia Alfonso <trishalfonso@google.com>,
	Shuah Khan <skhan@linuxfoundation.org>,
	"open list:KERNEL SELFTEST FRAMEWORK" 
	<linux-kselftest@vger.kernel.org>,
	KUnit Development <kunit-dev@googlegroups.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [RFC PATCH kunit-next 2/2] kunit: add support for named resources
Date: Thu, 12 Mar 2020 17:09:15 -0700	[thread overview]
Message-ID: <CAFd5g45mSdJ8rF2AAfr6BJrBuPrn=6ntz=Z8a+mj4_Ptjg7XLA@mail.gmail.com> (raw)
In-Reply-To: <1583251361-12748-3-git-send-email-alan.maguire@oracle.com>

On Tue, Mar 3, 2020 at 8:03 AM Alan Maguire <alan.maguire@oracle.com> wrote:
>
> The kunit resources API allows for custom initialization and
> cleanup code (init/fini); here we use the init code to set the
> new "struct kunit_resource" "name" field, and call an additional
> init function if needed.  Having a simple way to name resources
> is useful in cases such as multithreaded tests where a set of
> resources are shared among threads; a pointer to the
> "struct kunit *" test state then is all that is needed to
> retrieve and use named resources.  Support is provided to add,
> find and destroy named resources; the latter two are simply
> wrappers that use a "match-by-name" callback.
>
> If an attempt to add a resource with a name that already exists
> is made kunit_add_named_resource() will return NULL.
>
> Signed-off-by: Alan Maguire <alan.maguire@oracle.com>

Overall, I think this seems reasonable. I think it needs a use case to
be justified, so long as Patricia ends up using it.

Reviewed-by: Brendan Higgins <brendanhiggins@google.com>

> ---
>  include/kunit/test.h   | 40 ++++++++++++++++++++++++++++++++++++++-
>  lib/kunit/kunit-test.c | 37 ++++++++++++++++++++++++++++++++++++
>  lib/kunit/test.c       | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 127 insertions(+), 1 deletion(-)
>
> diff --git a/include/kunit/test.h b/include/kunit/test.h
> index 11c80f5..70ee581 100644
> --- a/include/kunit/test.h
> +++ b/include/kunit/test.h
> @@ -73,9 +73,14 @@
>   *                     kunit_kmalloc_free, &params);
>   *     }
>   *
> + * Resources can also be named, with lookup/removal done on a name
> + * basis also.  kunit_add_named_resource(), kunit_find_named_resource()
> + * and kunit_destroy_named_resource() below.  Resource names must be
> + * unique within the test instance.
>   */
>  struct kunit_resource {
>         void *data;
> +       const char *name;       /* optional name */
>         kunit_resource_init_t init;
>         kunit_resource_free_t free;
>
> @@ -275,12 +280,27 @@ struct kunit_resource *kunit_alloc_and_get_resource(struct kunit *test,
>   * @init: a user-supplied function to initialize the result (if needed).  If
>   *        none is supplied, the resource data value is simply set to @data.
>   *       If an init function is supplied, @data is passed to it instead.
> - * @free: a user-supplied function to free the resource (if needed).
> + * @free: a user-supplied function to free the resource data (if needed).
>   * @data: value to pass to init function or set in resource data field.
>   */
>  int kunit_add_resource(struct kunit *test, kunit_resource_init_t init,
>                        kunit_resource_free_t free, struct kunit_resource *res,
>                        void *data);
> +
> +/**
> + * kunit_add_named_resource() - Add a named *test managed resource*.
> + * @test: The test context object.
> + * @init: a user-supplied function to initialize the resource data, if needed.
> + * @free: a user-supplied function to free the resource data, if needed.
> + * @name_data: name and data to be set for resource.
> + */
> +int kunit_add_named_resource(struct kunit *test,
> +                            kunit_resource_init_t init,
> +                            kunit_resource_free_t free,
> +                            struct kunit_resource *res,
> +                            const char *name,
> +                            void *data);
> +
>  /**
>   * kunit_alloc_resource() - Allocates a *test managed resource*.
>   * @test: The test context object.
> @@ -336,6 +356,19 @@ static inline bool kunit_resource_instance_match(struct kunit *test,
>  }
>
>  /**
> + * kunit_resource_name_match() - Match a resource with the same name.
> + * @test: Test case to which the resource belongs.
> + * @res: The resource.
> + * @match_name: The name to match against.
> + */
> +static inline bool kunit_resource_name_match(struct kunit *test,
> +                                            struct kunit_resource *res,
> +                                            void *match_name)
> +{
> +       return res->name && strcmp(res->name, match_name) == 0;
> +}
> +
> +/**
>   * kunit_find_resource() - Find a resource using match function/data.
>   * @test: Test case to which the resource belongs.
>   * @match: match function to be applied to resources/match data.
> @@ -345,6 +378,9 @@ struct kunit_resource *kunit_find_resource(struct kunit *test,
>                                            kunit_resource_match_t match,
>                                            void *match_data);
>
> +#define kunit_find_named_resource(test, name)                  \
> +       kunit_find_resource(test, kunit_resource_name_match, (void *)name)
> +
>  /**
>   * kunit_destroy_resource() - Find a kunit_resource and destroy it.
>   * @test: Test case to which the resource belongs.
> @@ -358,6 +394,8 @@ int kunit_destroy_resource(struct kunit *test,
>                            kunit_resource_match_t match,
>                            void *match_data);
>
> +#define kunit_destroy_named_resource(test, name)               \
> +       kunit_destroy_resource(test, kunit_resource_name_match, name)

nit: I would prefer a static inline function here instead of a macro.

>  /**
>   * kunit_remove_resource: remove resource from resource list associated with
> diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c
> index b8bf36d..079c558 100644
> --- a/lib/kunit/kunit-test.c
> +++ b/lib/kunit/kunit-test.c
> @@ -317,6 +317,42 @@ static void kunit_resource_test_static(struct kunit *test)
>         KUNIT_EXPECT_TRUE(test, list_empty(&test->resources));
>  }
>
> +static void kunit_resource_test_named(struct kunit *test)
> +{
> +       struct kunit_resource res1, res2, *found = NULL;
> +       struct kunit_test_resource_context ctx;
> +
> +       KUNIT_EXPECT_EQ(test,
> +                       kunit_add_named_resource(test, NULL, NULL, &res1,
> +                                                "resource_1", &ctx),
> +                       0);
> +       KUNIT_EXPECT_PTR_EQ(test, res1.data, (void *)&ctx);
> +
> +       KUNIT_EXPECT_EQ(test,
> +                       kunit_add_named_resource(test, NULL, NULL, &res1,
> +                                                "resource_1", &ctx),
> +                       -EEXIST);
> +
> +       KUNIT_EXPECT_EQ(test,
> +                       kunit_add_named_resource(test, NULL, NULL, &res2,
> +                                                "resource_2", &ctx),
> +                       0);
> +
> +       found = kunit_find_named_resource(test, "resource_1");
> +
> +       KUNIT_EXPECT_PTR_EQ(test, found, &res1);
> +
> +       if (found)
> +               kunit_put_resource(&res1);
> +
> +       KUNIT_EXPECT_EQ(test, kunit_destroy_named_resource(test, "resource_2"),
> +                       0);
> +
> +       kunit_cleanup(test);
> +
> +       KUNIT_EXPECT_TRUE(test, list_empty(&test->resources));
> +}
> +
>  static int kunit_resource_test_init(struct kunit *test)
>  {
>         struct kunit_test_resource_context *ctx =
> @@ -346,6 +382,7 @@ static void kunit_resource_test_exit(struct kunit *test)
>         KUNIT_CASE(kunit_resource_test_cleanup_resources),
>         KUNIT_CASE(kunit_resource_test_proper_free_ordering),
>         KUNIT_CASE(kunit_resource_test_static),
> +       KUNIT_CASE(kunit_resource_test_named),
>         {}
>  };
>
> diff --git a/lib/kunit/test.c b/lib/kunit/test.c
> index 132e9bf..86a4d9c 100644
> --- a/lib/kunit/test.c
> +++ b/lib/kunit/test.c
> @@ -380,6 +380,57 @@ int kunit_add_resource(struct kunit *test, kunit_resource_init_t init,
>  }
>  EXPORT_SYMBOL_GPL(kunit_add_resource);
>
> +/* Used to initialize named resource. */
> +struct kunit_name_data {
> +       const char *name;
> +       kunit_resource_init_t init;
> +       void *data;
> +};
> +
> +static int kunit_init_named_resource(struct kunit_resource *res, void *data)
> +{
> +       struct kunit_name_data *name_data = data;
> +
> +       res->name = name_data->name;
> +       res->data = name_data->data;
> +       res->init = name_data->init;
> +
> +       if (res->init)
> +               return res->init(res, name_data->data);
> +
> +       res->data = name_data->data;
> +
> +       return 0;
> +}
> +
> +int kunit_add_named_resource(struct kunit *test,
> +                            kunit_resource_init_t init,
> +                            kunit_resource_free_t free,
> +                            struct kunit_resource *res,
> +                            const char *name,
> +                            void *data)
> +{
> +       struct kunit_name_data name_data;
> +       struct kunit_resource *existing;
> +
> +       if (!name)
> +               return -EINVAL;
> +
> +       existing = kunit_find_named_resource(test, name);
> +       if (existing) {
> +               kunit_put_resource(existing);
> +               return -EEXIST;
> +       }
> +
> +       name_data.name = name;
> +       name_data.init = init;
> +       name_data.data = data;
> +
> +       return kunit_add_resource(test, kunit_init_named_resource, free, res,
> +                                 &name_data);
> +}
> +EXPORT_SYMBOL_GPL(kunit_add_named_resource);

Could we maybe combine the above with the non-named variants? Seems
like there might be some unnecessary code duplication.

>  struct kunit_resource *kunit_alloc_and_get_resource(struct kunit *test,
>                                                     kunit_resource_init_t init,
>                                                     kunit_resource_free_t free,

Once again, thank you for all your hard work!

      reply	other threads:[~2020-03-13  0:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-03 16:02 [RFC PATCH kunit-next 0/2] kunit: extend kunit resources API Alan Maguire
2020-03-03 16:02 ` [RFC PATCH kunit-next 1/2] kunit: generalize kunit_resource API beyond allocated resources Alan Maguire
2020-03-04  3:10   ` kbuild test robot
2020-03-04  3:11   ` [RFC PATCH] kunit: kunit_release_resource() can be static kbuild test robot
2020-03-12  0:14   ` [RFC PATCH kunit-next 1/2] kunit: generalize kunit_resource API beyond allocated resources Brendan Higgins
2020-03-03 16:02 ` [RFC PATCH kunit-next 2/2] kunit: add support for named resources Alan Maguire
2020-03-13  0:09   ` Brendan Higgins [this message]

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='CAFd5g45mSdJ8rF2AAfr6BJrBuPrn=6ntz=Z8a+mj4_Ptjg7XLA@mail.gmail.com' \
    --to=brendanhiggins@google.com \
    --cc=alan.maguire@oracle.com \
    --cc=kunit-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=trishalfonso@google.com \
    /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.