Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

Kees Cook fc078392 2d8ae9a4

+218
+9
lib/Kconfig.debug
··· 2460 2460 2461 2461 If unsure, say N. 2462 2462 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 + 2463 2472 config STRING_KUNIT_TEST 2464 2473 tristate "KUnit test string functions at runtime" if !KUNIT_ALL_TESTS 2465 2474 depends on KUNIT
+1
lib/tests/Makefile
··· 37 37 obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o 38 38 obj-$(CONFIG_RANDSTRUCT_KUNIT_TEST) += randstruct_kunit.o 39 39 obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o 40 + obj-$(CONFIG_SEQ_BUF_KUNIT_TEST) += seq_buf_kunit.o 40 41 obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o 41 42 obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o 42 43 obj-$(CONFIG_TEST_SORT) += test_sort.o
+208
lib/tests/seq_buf_kunit.c
··· 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");