// SPDX-License-Identifier: GPL-2.0 /* * KUnit test for struct test_stream. * * Copyright (C) 2018, Google LLC. * Author: Brendan Higgins */ #include #include #include #include "test-mock.h" struct test_stream_test_context { struct MOCK(KUNIT_T) *mock_test; struct test_stream *stream; }; static void test_stream_test_add(struct KUNIT_T *test) { struct test_stream_test_context *ctx = test->priv; struct MOCK(KUNIT_T) *mock_test = NICE_MOCK(ctx->mock_test); struct test_stream *stream = ctx->stream; stream->add(stream, "Foo"); stream->add(stream, " %s", "bar"); stream->set_level(stream, KERN_INFO); EXPECT_CALL(mock_vprintk(mock_get_ctrl(mock_test), any(test), va_format_cmp(test, streq(test, "Foo bar"), any(test)))); stream->commit(stream); } static void test_stream_test_append(struct KUNIT_T *test) { struct test_stream_test_context *ctx = test->priv; struct MOCK(KUNIT_T) *mock_test = NICE_MOCK(ctx->mock_test); struct test_stream *stream = ctx->stream; struct test_stream *other_stream; stream->add(stream, "Foo"); stream->set_level(stream, KERN_INFO); other_stream = test_new_stream(mock_get_trgt(mock_test)); other_stream->add(other_stream, " %s", "bar"); stream->append(stream, other_stream); EXPECT_CALL(mock_vprintk(mock_get_ctrl(mock_test), any(test), va_format_cmp(test, streq(test, "Foo bar"), any(test)))); stream->commit(stream); } static void test_stream_error_message_when_no_level_set(struct KUNIT_T *test) { struct test_stream_test_context *ctx = test->priv; struct MOCK(KUNIT_T) *mock_test = NICE_MOCK(ctx->mock_test); struct test_stream *stream = ctx->stream; struct test_stream *other_stream; stream->add(stream, "Foo bar"); other_stream = test_new_stream(mock_get_trgt(mock_test)); stream->append(stream, other_stream); EXPECT_CALL(mock_vprintk(mock_get_ctrl(mock_test), any(test), va_format_cmp(test, streq(test, "Stream was committed without a specified log level."), any(test)))); EXPECT_CALL(mock_vprintk(mock_get_ctrl(mock_test), any(test), va_format_cmp(test, streq(test, "Foo bar"), any(test)))); stream->commit(stream); } static int test_stream_test_init(struct KUNIT_T *test) { struct mock_struct_formatter_entry *entries; struct test_stream_test_context *ctx; ctx = test_kzalloc(test, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; test->priv = ctx; ctx->mock_test = CONSTRUCT_MOCK(KUNIT_T, test); if (!ctx->mock_test) return -EINVAL; ctx->stream = test_new_stream(mock_get_trgt(ctx->mock_test)); if (!ctx->stream) return -ENOMEM; entries = test_kzalloc(test, sizeof(*entries) * 3, GFP_KERNEL); if (!entries) { test_warn(test, "Could not allocate arg formatter for struct va_format"); return 0; } INIT_MOCK_STRUCT_FORMATTER_ENTRY(&entries[0], struct va_format, fmt, FORMATTER_FROM_TYPE(const char *)); INIT_MOCK_STRUCT_FORMATTER_ENTRY(&entries[1], struct va_format, va, unknown_formatter); INIT_MOCK_STRUCT_FORMATTER_ENTRY_LAST(&entries[2]); mock_register_formatter(mock_struct_formatter(test, "struct va_format *", entries)); return 0; } static void test_stream_test_commits_any_uncommitted_when_cleanup( struct KUNIT_T *test) { struct test_stream_test_context *ctx = test->priv; struct MOCK(KUNIT_T) *mock_test = NICE_MOCK(ctx->mock_test); struct test_stream *stream = ctx->stream; stream->add(stream, "Hello World"); stream->set_level(stream, KERN_WARNING); EXPECT_CALL(mock_vprintk(mock_get_ctrl(mock_test), any(test), va_format_cmp(test, streq(test, "End of test case reached with uncommitted stream entries."), any(test)))); EXPECT_CALL(mock_vprintk(mock_get_ctrl(mock_test), any(test), va_format_cmp(test, streq(test, "Hello World"), any(test)))); test_cleanup(mock_get_trgt(mock_test)); } static void test_stream_test_exit(struct KUNIT_T *test) { mock_unregister_formatter(mock_find_formatter("struct va_format *")); } static struct KUNIT_CASE_T test_stream_test_cases[] = { TEST_CASE(test_stream_test_add), TEST_CASE(test_stream_test_append), TEST_CASE(test_stream_test_commits_any_uncommitted_when_cleanup), TEST_CASE(test_stream_error_message_when_no_level_set), {}, }; static struct KUNIT_SUITE_T test_stream_test_module = { .name = "test-stream-test", .init = test_stream_test_init, .exit = test_stream_test_exit, .test_cases = test_stream_test_cases, }; module_test(test_stream_test_module);