On Wed, Aug 9, 2023 at 10:54 AM Richard Fitzgerald <rf@xxxxxxxxxxxxxxxxxxxxx> wrote: > > Add kunit_log_long_line_test() to test that logging a line longer than > the buffer fragment size doesn't truncate the line. > > Add extra tests to kunit_log_newline_test() for lines longer than the > buffer fragment size. > > Signed-off-by: Richard Fitzgerald <rf@xxxxxxxxxxxxxxxxxxxxx> Hello! This test looks good to me. I have included just a few comments below. Reviewed-by: Rae Moar <rmoar@xxxxxxxxxx> Thanks! -Rae > --- > lib/kunit/kunit-test.c | 84 +++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 83 insertions(+), 1 deletion(-) > > diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c > index 9ac81828d018..c079550c3afd 100644 > --- a/lib/kunit/kunit-test.c > +++ b/lib/kunit/kunit-test.c > @@ -609,7 +609,7 @@ static void kunit_log_newline_test(struct kunit *test) > { > struct kunit_suite suite; > struct kunit_log_frag *frag; > - char *p; > + char *p, *line; > > kunit_info(test, "Add newline\n"); > if (test->log) { > @@ -635,6 +635,33 @@ static void kunit_log_newline_test(struct kunit *test) > KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); > KUNIT_EXPECT_NOT_NULL_MSG(test, strstr(p, "x12345678\n"), > "Newline not appended when fragment is full. Log is:\n'%s'", p); > + kunit_kfree(test, p); > + I really like the thoroughness of this test. However, I do wonder if this newline test could be broken into at least 2 parts as the test is quite long with all these additions. I spoke on this in a previous patch and just wanted to touch on it here as well. > + /* String that is much longer than a fragment */ > + line = kunit_kzalloc(test, sizeof(frag->buf) * 6, GFP_KERNEL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, line); > + memset(line, 'x', (sizeof(frag->buf) * 6) - 1); > + kunit_log_append(suite.log, "%s", line); > + p = get_concatenated_log(test, suite.log, NULL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); > + KUNIT_EXPECT_EQ(test, p[strlen(p) - 1], '\n'); > + KUNIT_EXPECT_NULL(test, strstr(p, "\n\n")); > + kunit_kfree(test, p); > + I would also consider adding comments between these three cases to describe their differences and maybe what the desired behavior would be. > + kunit_log_append(suite.log, "%s\n", line); > + p = get_concatenated_log(test, suite.log, NULL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); > + KUNIT_EXPECT_EQ(test, p[strlen(p) - 1], '\n'); > + KUNIT_EXPECT_NULL(test, strstr(p, "\n\n")); > + kunit_kfree(test, p); > + > + line[strlen(line) - 1] = '\n'; > + kunit_log_append(suite.log, "%s", line); > + p = get_concatenated_log(test, suite.log, NULL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); > + KUNIT_EXPECT_EQ(test, p[strlen(p) - 1], '\n'); > + KUNIT_EXPECT_NULL(test, strstr(p, "\n\n")); > + kunit_kfree(test, p); > } else { > kunit_skip(test, "only useful when debugfs is enabled"); > } > @@ -799,6 +826,60 @@ static void kunit_log_frag_sized_line_test(struct kunit *test) > #endif > } > > +static void kunit_log_long_line_test(struct kunit *test) > +{ > +#ifdef CONFIG_KUNIT_DEBUGFS > + struct kunit_suite suite; > + struct kunit_log_frag *frag; > + struct rnd_state rnd; > + char *line, *p, *pn; > + size_t line_buf_size, len; > + int num_frags, i; > + > + suite.log = kunit_kzalloc(test, sizeof(*suite.log), GFP_KERNEL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, suite.log); > + INIT_LIST_HEAD(suite.log); > + frag = kunit_kmalloc(test, sizeof(*frag), GFP_KERNEL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, frag); > + kunit_init_log_frag(frag); > + KUNIT_EXPECT_EQ(test, frag->buf[0], '\0'); > + list_add_tail(&frag->list, suite.log); > + > + /* Create a very long string to be logged */ > + line_buf_size = sizeof(frag->buf) * 6; > + line = kunit_kmalloc(test, line_buf_size, GFP_KERNEL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, line); > + line[0] = '\0'; > + > + prandom_seed_state(&rnd, 3141592653589793238ULL); I was a little worried about including a randomized string but since it does not need to be reproduced here it should be fine. I also haven't seen any issues with the tests with the randomized strings being nondeterministic. > + len = 0; > + do { > + static const char fill[] = > + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; > + > + i = prandom_u32_state(&rnd) % (sizeof(fill) - 1); > + len = strlcat(line, &fill[i], line_buf_size); > + } while (len < line_buf_size); > + > + kunit_log_append(suite.log, "%s\n", line); > + > + p = get_concatenated_log(test, suite.log, &num_frags); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); > + KUNIT_EXPECT_GT(test, num_frags, 1); > + > + kunit_info(test, "num_frags:%d total len:%zu\n", num_frags, strlen(p)); > + > + /* Don't compare the trailing '\n' */ > + pn = strrchr(p, '\n'); > + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, pn); > + *pn = '\0'; > + KUNIT_EXPECT_EQ(test, strlen(p), strlen(line)); > + KUNIT_EXPECT_STREQ(test, p, line); > +#else > + kunit_skip(test, "only useful when debugfs is enabled"); > +#endif > +} > + > static struct kunit_case kunit_log_test_cases[] = { > KUNIT_CASE(kunit_log_init_frag_test), > KUNIT_CASE(kunit_log_test), > @@ -806,6 +887,7 @@ static struct kunit_case kunit_log_test_cases[] = { > KUNIT_CASE(kunit_log_extend_test_1), > KUNIT_CASE(kunit_log_extend_test_2), > KUNIT_CASE(kunit_log_frag_sized_line_test), > + KUNIT_CASE(kunit_log_long_line_test), > {} > }; > > -- > 2.30.2 >