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 
seq_buf_init_test(struct kunit * test)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 
seq_buf_declare_test(struct kunit * test)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 
seq_buf_clear_test(struct kunit * test)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 
seq_buf_puts_test(struct kunit * test)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 
seq_buf_puts_overflow_test(struct kunit * test)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 
seq_buf_putc_test(struct kunit * test)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 
seq_buf_printf_test(struct kunit * test)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 
seq_buf_printf_overflow_test(struct kunit * test)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 
seq_buf_get_buf_commit_test(struct kunit * test)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");
209