Skip to content

Commit fc07839

Browse files
committed
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/[email protected] Reviewed-by: David Gow <[email protected]> Signed-off-by: Kees Cook <[email protected]>
1 parent 2d8ae9a commit fc07839

File tree

3 files changed

+218
-0
lines changed

3 files changed

+218
-0
lines changed

lib/Kconfig.debug

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2460,6 +2460,15 @@ config SCANF_KUNIT_TEST
24602460

24612461
If unsure, say N.
24622462

2463+
config SEQ_BUF_KUNIT_TEST
2464+
tristate "KUnit test for seq_buf" if !KUNIT_ALL_TESTS
2465+
depends on KUNIT
2466+
default KUNIT_ALL_TESTS
2467+
help
2468+
This builds unit tests for the seq_buf library.
2469+
2470+
If unsure, say N.
2471+
24632472
config STRING_KUNIT_TEST
24642473
tristate "KUnit test string functions at runtime" if !KUNIT_ALL_TESTS
24652474
depends on KUNIT

lib/tests/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
3737
obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o
3838
obj-$(CONFIG_RANDSTRUCT_KUNIT_TEST) += randstruct_kunit.o
3939
obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o
40+
obj-$(CONFIG_SEQ_BUF_KUNIT_TEST) += seq_buf_kunit.o
4041
obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
4142
obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o
4243
obj-$(CONFIG_TEST_SORT) += test_sort.o

lib/tests/seq_buf_kunit.c

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* KUnit tests for the seq_buf API
4+
*
5+
* Copyright (C) 2025, Google LLC.
6+
*/
7+
8+
#include <kunit/test.h>
9+
#include <linux/seq_buf.h>
10+
11+
static void seq_buf_init_test(struct kunit *test)
12+
{
13+
char buf[32];
14+
struct seq_buf s;
15+
16+
seq_buf_init(&s, buf, sizeof(buf));
17+
18+
KUNIT_EXPECT_EQ(test, s.size, 32);
19+
KUNIT_EXPECT_EQ(test, s.len, 0);
20+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
21+
KUNIT_EXPECT_EQ(test, seq_buf_buffer_left(&s), 32);
22+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 0);
23+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
24+
}
25+
26+
static void seq_buf_declare_test(struct kunit *test)
27+
{
28+
DECLARE_SEQ_BUF(s, 24);
29+
30+
KUNIT_EXPECT_EQ(test, s.size, 24);
31+
KUNIT_EXPECT_EQ(test, s.len, 0);
32+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
33+
KUNIT_EXPECT_EQ(test, seq_buf_buffer_left(&s), 24);
34+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 0);
35+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
36+
}
37+
38+
static void seq_buf_clear_test(struct kunit *test)
39+
{
40+
DECLARE_SEQ_BUF(s, 128);
41+
42+
seq_buf_puts(&s, "hello");
43+
KUNIT_EXPECT_EQ(test, s.len, 5);
44+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
45+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello");
46+
47+
seq_buf_clear(&s);
48+
49+
KUNIT_EXPECT_EQ(test, s.len, 0);
50+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
51+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
52+
}
53+
54+
static void seq_buf_puts_test(struct kunit *test)
55+
{
56+
DECLARE_SEQ_BUF(s, 16);
57+
58+
seq_buf_puts(&s, "hello");
59+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 5);
60+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
61+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello");
62+
63+
seq_buf_puts(&s, " world");
64+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
65+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
66+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world");
67+
}
68+
69+
static void seq_buf_puts_overflow_test(struct kunit *test)
70+
{
71+
DECLARE_SEQ_BUF(s, 10);
72+
73+
seq_buf_puts(&s, "123456789");
74+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
75+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 9);
76+
77+
seq_buf_puts(&s, "0");
78+
KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
79+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 10);
80+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "123456789");
81+
82+
seq_buf_clear(&s);
83+
KUNIT_EXPECT_EQ(test, s.len, 0);
84+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
85+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
86+
}
87+
88+
static void seq_buf_putc_test(struct kunit *test)
89+
{
90+
DECLARE_SEQ_BUF(s, 4);
91+
92+
seq_buf_putc(&s, 'a');
93+
seq_buf_putc(&s, 'b');
94+
seq_buf_putc(&s, 'c');
95+
96+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 3);
97+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
98+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "abc");
99+
100+
seq_buf_putc(&s, 'd');
101+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 4);
102+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
103+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "abc");
104+
105+
seq_buf_putc(&s, 'e');
106+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 4);
107+
KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
108+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "abc");
109+
110+
seq_buf_clear(&s);
111+
KUNIT_EXPECT_EQ(test, s.len, 0);
112+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
113+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
114+
}
115+
116+
static void seq_buf_printf_test(struct kunit *test)
117+
{
118+
DECLARE_SEQ_BUF(s, 32);
119+
120+
seq_buf_printf(&s, "hello %s", "world");
121+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
122+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
123+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world");
124+
125+
seq_buf_printf(&s, " %d", 123);
126+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 15);
127+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
128+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world 123");
129+
}
130+
131+
static void seq_buf_printf_overflow_test(struct kunit *test)
132+
{
133+
DECLARE_SEQ_BUF(s, 16);
134+
135+
seq_buf_printf(&s, "%lu", 1234567890UL);
136+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
137+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 10);
138+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "1234567890");
139+
140+
seq_buf_printf(&s, "%s", "abcdefghij");
141+
KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
142+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 16);
143+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "1234567890abcde");
144+
145+
seq_buf_clear(&s);
146+
KUNIT_EXPECT_EQ(test, s.len, 0);
147+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
148+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
149+
}
150+
151+
static void seq_buf_get_buf_commit_test(struct kunit *test)
152+
{
153+
DECLARE_SEQ_BUF(s, 16);
154+
char *buf;
155+
size_t len;
156+
157+
len = seq_buf_get_buf(&s, &buf);
158+
KUNIT_EXPECT_EQ(test, len, 16);
159+
KUNIT_EXPECT_PTR_NE(test, buf, NULL);
160+
161+
memcpy(buf, "hello", 5);
162+
seq_buf_commit(&s, 5);
163+
164+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 5);
165+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
166+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello");
167+
168+
len = seq_buf_get_buf(&s, &buf);
169+
KUNIT_EXPECT_EQ(test, len, 11);
170+
KUNIT_EXPECT_PTR_NE(test, buf, NULL);
171+
172+
memcpy(buf, " worlds!", 8);
173+
seq_buf_commit(&s, 6);
174+
175+
KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
176+
KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
177+
KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world");
178+
179+
len = seq_buf_get_buf(&s, &buf);
180+
KUNIT_EXPECT_EQ(test, len, 5);
181+
KUNIT_EXPECT_PTR_NE(test, buf, NULL);
182+
183+
seq_buf_commit(&s, -1);
184+
KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
185+
}
186+
187+
static struct kunit_case seq_buf_test_cases[] = {
188+
KUNIT_CASE(seq_buf_init_test),
189+
KUNIT_CASE(seq_buf_declare_test),
190+
KUNIT_CASE(seq_buf_clear_test),
191+
KUNIT_CASE(seq_buf_puts_test),
192+
KUNIT_CASE(seq_buf_puts_overflow_test),
193+
KUNIT_CASE(seq_buf_putc_test),
194+
KUNIT_CASE(seq_buf_printf_test),
195+
KUNIT_CASE(seq_buf_printf_overflow_test),
196+
KUNIT_CASE(seq_buf_get_buf_commit_test),
197+
{}
198+
};
199+
200+
static struct kunit_suite seq_buf_test_suite = {
201+
.name = "seq_buf",
202+
.test_cases = seq_buf_test_cases,
203+
};
204+
205+
kunit_test_suite(seq_buf_test_suite);
206+
207+
MODULE_DESCRIPTION("Runtime test cases for seq_buf string API");
208+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)