seq_buf: Introduce KUnit tests
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>pull/1309/head
parent
2d8ae9a4f1
commit
fc07839203
|
|
@ -2460,6 +2460,15 @@ config SCANF_KUNIT_TEST
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config SEQ_BUF_KUNIT_TEST
|
||||
tristate "KUnit test for seq_buf" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
This builds unit tests for the seq_buf library.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config STRING_KUNIT_TEST
|
||||
tristate "KUnit test string functions at runtime" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
|
|||
obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o
|
||||
obj-$(CONFIG_RANDSTRUCT_KUNIT_TEST) += randstruct_kunit.o
|
||||
obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o
|
||||
obj-$(CONFIG_SEQ_BUF_KUNIT_TEST) += seq_buf_kunit.o
|
||||
obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
|
||||
obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o
|
||||
obj-$(CONFIG_TEST_SORT) += test_sort.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,208 @@
|
|||
// 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");
|
||||
Loading…
Reference in New Issue