| // 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"); |