mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Add KUnit tests for the seq_buf API to ensure its correctness and prevent future regressions, covering the following functions: - seq_buf_init() - DECLARE_SEQ_BUF() - seq_buf_clear() - seq_buf_puts() - seq_buf_putc() - seq_buf_printf() - seq_buf_get_buf() - seq_buf_commit() $ tools/testing/kunit/kunit.py run seq_buf =================== seq_buf (9 subtests) =================== [PASSED] seq_buf_init_test [PASSED] seq_buf_declare_test [PASSED] seq_buf_clear_test [PASSED] seq_buf_puts_test [PASSED] seq_buf_puts_overflow_test [PASSED] seq_buf_putc_test [PASSED] seq_buf_printf_test [PASSED] seq_buf_printf_overflow_test [PASSED] seq_buf_get_buf_commit_test ===================== [PASSED] seq_buf ===================== Link: https://lore.kernel.org/r/20250717085156.work.363-kees@kernel.org Reviewed-by: David Gow <davidgow@google.com> Signed-off-by: Kees Cook <kees@kernel.org>
208 lines
5.7 KiB
C
208 lines
5.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* KUnit tests for the seq_buf API
|
|
*
|
|
* Copyright (C) 2025, Google LLC.
|
|
*/
|
|
|
|
#include <kunit/test.h>
|
|
#include <linux/seq_buf.h>
|
|
|
|
static void seq_buf_init_test(struct kunit *test)
|
|
{
|
|
char buf[32];
|
|
struct seq_buf s;
|
|
|
|
seq_buf_init(&s, buf, sizeof(buf));
|
|
|
|
KUNIT_EXPECT_EQ(test, s.size, 32);
|
|
KUNIT_EXPECT_EQ(test, s.len, 0);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_EQ(test, seq_buf_buffer_left(&s), 32);
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 0);
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
|
|
}
|
|
|
|
static void seq_buf_declare_test(struct kunit *test)
|
|
{
|
|
DECLARE_SEQ_BUF(s, 24);
|
|
|
|
KUNIT_EXPECT_EQ(test, s.size, 24);
|
|
KUNIT_EXPECT_EQ(test, s.len, 0);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_EQ(test, seq_buf_buffer_left(&s), 24);
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 0);
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
|
|
}
|
|
|
|
static void seq_buf_clear_test(struct kunit *test)
|
|
{
|
|
DECLARE_SEQ_BUF(s, 128);
|
|
|
|
seq_buf_puts(&s, "hello");
|
|
KUNIT_EXPECT_EQ(test, s.len, 5);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello");
|
|
|
|
seq_buf_clear(&s);
|
|
|
|
KUNIT_EXPECT_EQ(test, s.len, 0);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
|
|
}
|
|
|
|
static void seq_buf_puts_test(struct kunit *test)
|
|
{
|
|
DECLARE_SEQ_BUF(s, 16);
|
|
|
|
seq_buf_puts(&s, "hello");
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 5);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello");
|
|
|
|
seq_buf_puts(&s, " world");
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world");
|
|
}
|
|
|
|
static void seq_buf_puts_overflow_test(struct kunit *test)
|
|
{
|
|
DECLARE_SEQ_BUF(s, 10);
|
|
|
|
seq_buf_puts(&s, "123456789");
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 9);
|
|
|
|
seq_buf_puts(&s, "0");
|
|
KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 10);
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "123456789");
|
|
|
|
seq_buf_clear(&s);
|
|
KUNIT_EXPECT_EQ(test, s.len, 0);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
|
|
}
|
|
|
|
static void seq_buf_putc_test(struct kunit *test)
|
|
{
|
|
DECLARE_SEQ_BUF(s, 4);
|
|
|
|
seq_buf_putc(&s, 'a');
|
|
seq_buf_putc(&s, 'b');
|
|
seq_buf_putc(&s, 'c');
|
|
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 3);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "abc");
|
|
|
|
seq_buf_putc(&s, 'd');
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 4);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "abc");
|
|
|
|
seq_buf_putc(&s, 'e');
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 4);
|
|
KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "abc");
|
|
|
|
seq_buf_clear(&s);
|
|
KUNIT_EXPECT_EQ(test, s.len, 0);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
|
|
}
|
|
|
|
static void seq_buf_printf_test(struct kunit *test)
|
|
{
|
|
DECLARE_SEQ_BUF(s, 32);
|
|
|
|
seq_buf_printf(&s, "hello %s", "world");
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world");
|
|
|
|
seq_buf_printf(&s, " %d", 123);
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 15);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world 123");
|
|
}
|
|
|
|
static void seq_buf_printf_overflow_test(struct kunit *test)
|
|
{
|
|
DECLARE_SEQ_BUF(s, 16);
|
|
|
|
seq_buf_printf(&s, "%lu", 1234567890UL);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 10);
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "1234567890");
|
|
|
|
seq_buf_printf(&s, "%s", "abcdefghij");
|
|
KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 16);
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "1234567890abcde");
|
|
|
|
seq_buf_clear(&s);
|
|
KUNIT_EXPECT_EQ(test, s.len, 0);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
|
|
}
|
|
|
|
static void seq_buf_get_buf_commit_test(struct kunit *test)
|
|
{
|
|
DECLARE_SEQ_BUF(s, 16);
|
|
char *buf;
|
|
size_t len;
|
|
|
|
len = seq_buf_get_buf(&s, &buf);
|
|
KUNIT_EXPECT_EQ(test, len, 16);
|
|
KUNIT_EXPECT_PTR_NE(test, buf, NULL);
|
|
|
|
memcpy(buf, "hello", 5);
|
|
seq_buf_commit(&s, 5);
|
|
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 5);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello");
|
|
|
|
len = seq_buf_get_buf(&s, &buf);
|
|
KUNIT_EXPECT_EQ(test, len, 11);
|
|
KUNIT_EXPECT_PTR_NE(test, buf, NULL);
|
|
|
|
memcpy(buf, " worlds!", 8);
|
|
seq_buf_commit(&s, 6);
|
|
|
|
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
|
|
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
|
|
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world");
|
|
|
|
len = seq_buf_get_buf(&s, &buf);
|
|
KUNIT_EXPECT_EQ(test, len, 5);
|
|
KUNIT_EXPECT_PTR_NE(test, buf, NULL);
|
|
|
|
seq_buf_commit(&s, -1);
|
|
KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
|
|
}
|
|
|
|
static struct kunit_case seq_buf_test_cases[] = {
|
|
KUNIT_CASE(seq_buf_init_test),
|
|
KUNIT_CASE(seq_buf_declare_test),
|
|
KUNIT_CASE(seq_buf_clear_test),
|
|
KUNIT_CASE(seq_buf_puts_test),
|
|
KUNIT_CASE(seq_buf_puts_overflow_test),
|
|
KUNIT_CASE(seq_buf_putc_test),
|
|
KUNIT_CASE(seq_buf_printf_test),
|
|
KUNIT_CASE(seq_buf_printf_overflow_test),
|
|
KUNIT_CASE(seq_buf_get_buf_commit_test),
|
|
{}
|
|
};
|
|
|
|
static struct kunit_suite seq_buf_test_suite = {
|
|
.name = "seq_buf",
|
|
.test_cases = seq_buf_test_cases,
|
|
};
|
|
|
|
kunit_test_suite(seq_buf_test_suite);
|
|
|
|
MODULE_DESCRIPTION("Runtime test cases for seq_buf string API");
|
|
MODULE_LICENSE("GPL");
|