| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * KUnit test for core test infrastructure. |
| * |
| * Copyright (C) 2018, Google LLC. |
| * Author: Brendan Higgins <brendanhiggins@google.com> |
| */ |
| #include <kunit/test.h> |
| |
| static void kunit_test_catches_segfault(struct kunit *test) |
| { |
| void (*invalid_func)(void) = (void (*)(void)) SIZE_MAX; |
| |
| KUNIT_ASSERT_SIGSEGV(test, invalid_func()); |
| } |
| |
| /* |
| * Context for testing test managed resources |
| * is_resource_initialized is used to test arbitrary resources |
| */ |
| struct kunit_test_context { |
| struct kunit test; |
| bool is_resource_initialized; |
| }; |
| |
| static int fake_resource_init(struct kunit_resource *res, void *context) |
| { |
| struct kunit_test_context *ctx = context; |
| |
| res->allocation = &ctx->is_resource_initialized; |
| ctx->is_resource_initialized = true; |
| return 0; |
| } |
| |
| static void fake_resource_free(struct kunit_resource *res) |
| { |
| bool *is_resource_initialized = res->allocation; |
| |
| *is_resource_initialized = false; |
| } |
| |
| static void kunit_test_init_resources(struct kunit *test) |
| { |
| struct kunit_test_context *ctx = test->priv; |
| |
| kunit_init_test(&ctx->test, "testing_test_init_test"); |
| |
| KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); |
| } |
| |
| static void kunit_test_alloc_resource(struct kunit *test) |
| { |
| struct kunit_test_context *ctx = test->priv; |
| struct kunit_resource *res; |
| kunit_resource_free_t free = fake_resource_free; |
| |
| res = kunit_alloc_resource(&ctx->test, |
| fake_resource_init, |
| fake_resource_free, |
| ctx); |
| |
| KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res); |
| KUNIT_EXPECT_EQ(test, &ctx->is_resource_initialized, res->allocation); |
| KUNIT_EXPECT_TRUE(test, list_is_last(&res->node, &ctx->test.resources)); |
| KUNIT_EXPECT_EQ(test, free, res->free); |
| } |
| |
| static void kunit_test_free_resource(struct kunit *test) |
| { |
| struct kunit_test_context *ctx = test->priv; |
| struct kunit_resource *res = kunit_alloc_resource(&ctx->test, |
| fake_resource_init, |
| fake_resource_free, |
| ctx); |
| |
| kunit_free_resource(&ctx->test, res); |
| |
| KUNIT_EXPECT_EQ(test, false, ctx->is_resource_initialized); |
| KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); |
| } |
| |
| static void kunit_test_cleanup_resources(struct kunit *test) |
| { |
| int i; |
| const int num_res = 5; |
| struct kunit_test_context *ctx = test->priv; |
| struct kunit_resource *resources[num_res]; |
| |
| for (i = 0; i < num_res; i++) { |
| resources[i] = kunit_alloc_resource(&ctx->test, |
| fake_resource_init, |
| fake_resource_free, |
| ctx); |
| } |
| |
| kunit_cleanup(&ctx->test); |
| |
| KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); |
| } |
| |
| static int kunit_test_init(struct kunit *test) |
| { |
| struct kunit_test_context *ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
| |
| if (!ctx) |
| return -ENOMEM; |
| test->priv = ctx; |
| |
| kunit_init_test(&ctx->test, "test_test_context"); |
| return 0; |
| } |
| |
| static void kunit_test_exit(struct kunit *test) |
| { |
| struct kunit_test_context *ctx = test->priv; |
| |
| kunit_cleanup(&ctx->test); |
| kfree(ctx); |
| } |
| |
| static struct kunit_case kunit_test_cases[] = { |
| KUNIT_CASE(kunit_test_catches_segfault), |
| KUNIT_CASE(kunit_test_init_resources), |
| KUNIT_CASE(kunit_test_alloc_resource), |
| KUNIT_CASE(kunit_test_free_resource), |
| KUNIT_CASE(kunit_test_cleanup_resources), |
| {}, |
| }; |
| |
| static struct kunit_module kunit_test_module = { |
| .name = "kunit-test", |
| .init = kunit_test_init, |
| .exit = kunit_test_exit, |
| .test_cases = kunit_test_cases, |
| }; |
| module_test(kunit_test_module); |