Commit 725aca95 authored by Alan Maguire's avatar Alan Maguire Committed by Shuah Khan
Browse files

kunit: add support for named resources



The kunit resources API allows for custom initialization and
cleanup code (init/fini); here a new resource add function sets
the "struct kunit_resource" "name" field, and calls the standard
add function.  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 -EEXIST.

Signed-off-by: default avatarAlan Maguire <alan.maguire@oracle.com>
Reviewed-by: default avatarBrendan Higgins <brendanhiggins@google.com>
Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
parent d4cdd146
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -72,9 +72,15 @@ typedef void (*kunit_resource_free_t)(struct kunit_resource *);
 *		return kunit_alloc_resource(test, kunit_kmalloc_init,
 *			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().  Resource names must be
 * unique within the test instance.
 */
struct kunit_resource {
	void *data;
	const char *name;		/* optional name */

	/* private: internal use only. */
	kunit_resource_free_t free;
@@ -344,6 +350,21 @@ int kunit_add_resource(struct kunit *test,
		       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.
@@ -398,6 +419,19 @@ static inline bool kunit_resource_instance_match(struct kunit *test,
	return res->data == match_data;
}

/**
 * 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.
@@ -426,6 +460,19 @@ kunit_find_resource(struct kunit *test,
	return found;
}

/**
 * kunit_find_named_resource() - Find a resource using match name.
 * @test: Test case to which the resource belongs.
 * @name: match name.
 */
static inline struct kunit_resource *
kunit_find_named_resource(struct kunit *test,
			  const char *name)
{
	return 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.
@@ -439,6 +486,13 @@ int kunit_destroy_resource(struct kunit *test,
			   kunit_resource_match_t match,
			   void *match_data);

static inline int kunit_destroy_named_resource(struct kunit *test,
					       const char *name)
{
	return kunit_destroy_resource(test, kunit_resource_name_match,
				      (void *)name);
}

/**
 * kunit_remove_resource: remove resource from resource list associated with
 *			  test.
+37 −0
Original line number Diff line number Diff line
@@ -325,6 +325,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 =
@@ -354,6 +390,7 @@ static struct kunit_case kunit_resource_test_cases[] = {
	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),
	{}
};

+24 −0
Original line number Diff line number Diff line
@@ -441,6 +441,30 @@ int kunit_add_resource(struct kunit *test,
}
EXPORT_SYMBOL_GPL(kunit_add_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)
{
	struct kunit_resource *existing;

	if (!name)
		return -EINVAL;

	existing = kunit_find_named_resource(test, name);
	if (existing) {
		kunit_put_resource(existing);
		return -EEXIST;
	}

	res->name = name;

	return kunit_add_resource(test, init, free, res, data);
}
EXPORT_SYMBOL_GPL(kunit_add_named_resource);

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