Skip to content

Commit 83b3370

Browse files
committed
Merge branch 'kunit' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git
2 parents 1216ad2 + 8040345 commit 83b3370

File tree

11 files changed

+734
-147
lines changed

11 files changed

+734
-147
lines changed

include/kunit/test.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@
3333
DECLARE_STATIC_KEY_FALSE(kunit_running);
3434

3535
struct kunit;
36-
37-
/* Size of log associated with test. */
38-
#define KUNIT_LOG_SIZE 2048
36+
struct string_stream;
3937

4038
/* Maximum size of parameter description string. */
4139
#define KUNIT_PARAM_DESC_SIZE 128
@@ -133,7 +131,7 @@ struct kunit_case {
133131
/* private: internal use only. */
134132
enum kunit_status status;
135133
char *module_name;
136-
char *log;
134+
struct string_stream *log;
137135
};
138136

139137
static inline char *kunit_status_to_ok_not_ok(enum kunit_status status)
@@ -253,7 +251,7 @@ struct kunit_suite {
253251
/* private: internal use only */
254252
char status_comment[KUNIT_STATUS_COMMENT_SIZE];
255253
struct dentry *debugfs;
256-
char *log;
254+
struct string_stream *log;
257255
int suite_init_err;
258256
};
259257

@@ -279,7 +277,7 @@ struct kunit {
279277

280278
/* private: internal use only. */
281279
const char *name; /* Read only after initialization! */
282-
char *log; /* Points at case log after initialization */
280+
struct string_stream *log; /* Points at case log after initialization */
283281
struct kunit_try_catch try_catch;
284282
/* param_value is the current parameter value for a test case. */
285283
const void *param_value;
@@ -315,7 +313,7 @@ const char *kunit_filter_glob(void);
315313
char *kunit_filter(void);
316314
char *kunit_filter_action(void);
317315

318-
void kunit_init_test(struct kunit *test, const char *name, char *log);
316+
void kunit_init_test(struct kunit *test, const char *name, struct string_stream *log);
319317

320318
int kunit_run_tests(struct kunit_suite *suite);
321319

@@ -473,7 +471,7 @@ static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp
473471

474472
void kunit_cleanup(struct kunit *test);
475473

476-
void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...);
474+
void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, ...);
477475

478476
/**
479477
* kunit_mark_skipped() - Marks @test_or_suite as skipped

lib/kunit/assert.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
8989
EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format);
9090

9191
/* Checks if `text` is a literal representing `value`, e.g. "5" and 5 */
92-
static bool is_literal(struct kunit *test, const char *text, long long value,
93-
gfp_t gfp)
92+
static bool is_literal(const char *text, long long value)
9493
{
9594
char *buffer;
9695
int len;
@@ -100,14 +99,15 @@ static bool is_literal(struct kunit *test, const char *text, long long value,
10099
if (strlen(text) != len)
101100
return false;
102101

103-
buffer = kunit_kmalloc(test, len+1, gfp);
102+
buffer = kmalloc(len+1, GFP_KERNEL);
104103
if (!buffer)
105104
return false;
106105

107106
snprintf(buffer, len+1, "%lld", value);
108107
ret = strncmp(buffer, text, len) == 0;
109108

110-
kunit_kfree(test, buffer);
109+
kfree(buffer);
110+
111111
return ret;
112112
}
113113

@@ -125,14 +125,12 @@ void kunit_binary_assert_format(const struct kunit_assert *assert,
125125
binary_assert->text->left_text,
126126
binary_assert->text->operation,
127127
binary_assert->text->right_text);
128-
if (!is_literal(stream->test, binary_assert->text->left_text,
129-
binary_assert->left_value, stream->gfp))
128+
if (!is_literal(binary_assert->text->left_text, binary_assert->left_value))
130129
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)\n",
131130
binary_assert->text->left_text,
132131
binary_assert->left_value,
133132
binary_assert->left_value);
134-
if (!is_literal(stream->test, binary_assert->text->right_text,
135-
binary_assert->right_value, stream->gfp))
133+
if (!is_literal(binary_assert->text->right_text, binary_assert->right_value))
136134
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)",
137135
binary_assert->text->right_text,
138136
binary_assert->right_value,

lib/kunit/debugfs.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,21 @@ void kunit_debugfs_init(void)
3737
debugfs_rootdir = debugfs_create_dir(KUNIT_DEBUGFS_ROOT, NULL);
3838
}
3939

40-
static void debugfs_print_result(struct seq_file *seq,
41-
struct kunit_suite *suite,
42-
struct kunit_case *test_case)
40+
static void debugfs_print_result(struct seq_file *seq, struct string_stream *log)
4341
{
44-
if (!test_case || !test_case->log)
42+
struct string_stream_fragment *frag_container;
43+
44+
if (!log)
4545
return;
4646

47-
seq_printf(seq, "%s", test_case->log);
47+
/*
48+
* Walk the fragments so we don't need to allocate a temporary
49+
* buffer to hold the entire string.
50+
*/
51+
spin_lock(&log->lock);
52+
list_for_each_entry(frag_container, &log->fragments, node)
53+
seq_printf(seq, "%s", frag_container->fragment);
54+
spin_unlock(&log->lock);
4855
}
4956

5057
/*
@@ -69,10 +76,9 @@ static int debugfs_print_results(struct seq_file *seq, void *v)
6976
seq_printf(seq, KUNIT_SUBTEST_INDENT "1..%zd\n", kunit_suite_num_test_cases(suite));
7077

7178
kunit_suite_for_each_test_case(suite, test_case)
72-
debugfs_print_result(seq, suite, test_case);
79+
debugfs_print_result(seq, test_case->log);
7380

74-
if (suite->log)
75-
seq_printf(seq, "%s", suite->log);
81+
debugfs_print_result(seq, suite->log);
7682

7783
seq_printf(seq, "%s %d %s\n",
7884
kunit_status_to_ok_not_ok(success), 1, suite->name);
@@ -105,9 +111,13 @@ void kunit_debugfs_create_suite(struct kunit_suite *suite)
105111
struct kunit_case *test_case;
106112

107113
/* Allocate logs before creating debugfs representation. */
108-
suite->log = kzalloc(KUNIT_LOG_SIZE, GFP_KERNEL);
109-
kunit_suite_for_each_test_case(suite, test_case)
110-
test_case->log = kzalloc(KUNIT_LOG_SIZE, GFP_KERNEL);
114+
suite->log = alloc_string_stream(GFP_KERNEL);
115+
string_stream_set_append_newlines(suite->log, true);
116+
117+
kunit_suite_for_each_test_case(suite, test_case) {
118+
test_case->log = alloc_string_stream(GFP_KERNEL);
119+
string_stream_set_append_newlines(test_case->log, true);
120+
}
111121

112122
suite->debugfs = debugfs_create_dir(suite->name, debugfs_rootdir);
113123

@@ -121,7 +131,7 @@ void kunit_debugfs_destroy_suite(struct kunit_suite *suite)
121131
struct kunit_case *test_case;
122132

123133
debugfs_remove_recursive(suite->debugfs);
124-
kfree(suite->log);
134+
string_stream_destroy(suite->log);
125135
kunit_suite_for_each_test_case(suite, test_case)
126-
kfree(test_case->log);
136+
string_stream_destroy(test_case->log);
127137
}

lib/kunit/executor.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,10 @@ void kunit_free_suite_set(struct kunit_suite_set suite_set)
137137
{
138138
struct kunit_suite * const *suites;
139139

140-
for (suites = suite_set.start; suites < suite_set.end; suites++)
140+
for (suites = suite_set.start; suites < suite_set.end; suites++) {
141+
kfree((*suites)->test_cases);
141142
kfree(*suites);
143+
}
142144
kfree(suite_set.start);
143145
}
144146

@@ -155,10 +157,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
155157
struct kunit_suite_set filtered = {NULL, NULL};
156158
struct kunit_glob_filter parsed_glob;
157159
struct kunit_attr_filter *parsed_filters = NULL;
160+
struct kunit_suite * const *suites;
158161

159162
const size_t max = suite_set->end - suite_set->start;
160163

161-
copy = kmalloc_array(max, sizeof(*filtered.start), GFP_KERNEL);
164+
copy = kcalloc(max, sizeof(*filtered.start), GFP_KERNEL);
162165
if (!copy) { /* won't be able to run anything, return an empty set */
163166
return filtered;
164167
}
@@ -193,7 +196,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
193196
parsed_glob.test_glob);
194197
if (IS_ERR(filtered_suite)) {
195198
*err = PTR_ERR(filtered_suite);
196-
goto free_parsed_filters;
199+
goto free_filtered_suite;
197200
}
198201
}
199202
if (filter_count > 0 && parsed_filters != NULL) {
@@ -210,11 +213,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
210213
filtered_suite = new_filtered_suite;
211214

212215
if (*err)
213-
goto free_parsed_filters;
216+
goto free_filtered_suite;
214217

215218
if (IS_ERR(filtered_suite)) {
216219
*err = PTR_ERR(filtered_suite);
217-
goto free_parsed_filters;
220+
goto free_filtered_suite;
218221
}
219222
if (!filtered_suite)
220223
break;
@@ -229,6 +232,14 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
229232
filtered.start = copy_start;
230233
filtered.end = copy;
231234

235+
free_filtered_suite:
236+
if (*err) {
237+
for (suites = copy_start; suites < copy; suites++) {
238+
kfree((*suites)->test_cases);
239+
kfree(*suites);
240+
}
241+
}
242+
232243
free_parsed_filters:
233244
if (filter_count)
234245
kfree(parsed_filters);
@@ -241,7 +252,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
241252

242253
free_copy:
243254
if (*err)
244-
kfree(copy);
255+
kfree(copy_start);
245256

246257
return filtered;
247258
}

lib/kunit/executor_test.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <kunit/test.h>
1010
#include <kunit/attributes.h>
1111

12-
static void kfree_at_end(struct kunit *test, const void *to_free);
12+
static void free_suite_set_at_end(struct kunit *test, const void *to_free);
1313
static struct kunit_suite *alloc_fake_suite(struct kunit *test,
1414
const char *suite_name,
1515
struct kunit_case *test_cases);
@@ -56,7 +56,7 @@ static void filter_suites_test(struct kunit *test)
5656
got = kunit_filter_suites(&suite_set, "suite2", NULL, NULL, &err);
5757
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
5858
KUNIT_ASSERT_EQ(test, err, 0);
59-
kfree_at_end(test, got.start);
59+
free_suite_set_at_end(test, &got);
6060

6161
/* Validate we just have suite2 */
6262
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
@@ -82,7 +82,7 @@ static void filter_suites_test_glob_test(struct kunit *test)
8282
got = kunit_filter_suites(&suite_set, "suite2.test2", NULL, NULL, &err);
8383
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
8484
KUNIT_ASSERT_EQ(test, err, 0);
85-
kfree_at_end(test, got.start);
85+
free_suite_set_at_end(test, &got);
8686

8787
/* Validate we just have suite2 */
8888
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
@@ -109,7 +109,7 @@ static void filter_suites_to_empty_test(struct kunit *test)
109109

110110
got = kunit_filter_suites(&suite_set, "not_found", NULL, NULL, &err);
111111
KUNIT_ASSERT_EQ(test, err, 0);
112-
kfree_at_end(test, got.start); /* just in case */
112+
free_suite_set_at_end(test, &got); /* just in case */
113113

114114
KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
115115
"should be empty to indicate no match");
@@ -172,7 +172,7 @@ static void filter_attr_test(struct kunit *test)
172172
got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err);
173173
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
174174
KUNIT_ASSERT_EQ(test, err, 0);
175-
kfree_at_end(test, got.start);
175+
free_suite_set_at_end(test, &got);
176176

177177
/* Validate we just have normal_suite */
178178
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
@@ -200,7 +200,7 @@ static void filter_attr_empty_test(struct kunit *test)
200200

201201
got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err);
202202
KUNIT_ASSERT_EQ(test, err, 0);
203-
kfree_at_end(test, got.start); /* just in case */
203+
free_suite_set_at_end(test, &got); /* just in case */
204204

205205
KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
206206
"should be empty to indicate no match");
@@ -222,7 +222,7 @@ static void filter_attr_skip_test(struct kunit *test)
222222
got = kunit_filter_suites(&suite_set, NULL, filter, "skip", &err);
223223
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
224224
KUNIT_ASSERT_EQ(test, err, 0);
225-
kfree_at_end(test, got.start);
225+
free_suite_set_at_end(test, &got);
226226

227227
/* Validate we have both the slow and normal test */
228228
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
@@ -256,18 +256,26 @@ kunit_test_suites(&executor_test_suite);
256256

257257
/* Test helpers */
258258

259-
/* Use the resource API to register a call to kfree(to_free).
259+
static void free_suite_set(void *suite_set)
260+
{
261+
kunit_free_suite_set(*(struct kunit_suite_set *)suite_set);
262+
kfree(suite_set);
263+
}
264+
265+
/* Use the resource API to register a call to free_suite_set.
260266
* Since we never actually use the resource, it's safe to use on const data.
261267
*/
262-
static void kfree_at_end(struct kunit *test, const void *to_free)
268+
static void free_suite_set_at_end(struct kunit *test, const void *to_free)
263269
{
264-
/* kfree() handles NULL already, but avoid allocating a no-op cleanup. */
265-
if (IS_ERR_OR_NULL(to_free))
270+
struct kunit_suite_set *free;
271+
272+
if (!((struct kunit_suite_set *)to_free)->start)
266273
return;
267274

268-
kunit_add_action(test,
269-
(kunit_action_t *)kfree,
270-
(void *)to_free);
275+
free = kzalloc(sizeof(struct kunit_suite_set), GFP_KERNEL);
276+
*free = *(struct kunit_suite_set *)to_free;
277+
278+
kunit_add_action(test, free_suite_set, (void *)free);
271279
}
272280

273281
static struct kunit_suite *alloc_fake_suite(struct kunit *test,

lib/kunit/kunit-example-test.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ static void example_static_stub_test(struct kunit *test)
190190
static const struct example_param {
191191
int value;
192192
} example_params_array[] = {
193+
{ .value = 3, },
193194
{ .value = 2, },
194195
{ .value = 1, },
195196
{ .value = 0, },
@@ -213,8 +214,8 @@ static void example_params_test(struct kunit *test)
213214
KUNIT_ASSERT_NOT_NULL(test, param);
214215

215216
/* Test can be skipped on unsupported param values */
216-
if (!param->value)
217-
kunit_skip(test, "unsupported param value");
217+
if (!is_power_of_2(param->value))
218+
kunit_skip(test, "unsupported param value %d", param->value);
218219

219220
/* You can use param values for parameterized testing */
220221
KUNIT_EXPECT_EQ(test, param->value % param->value, 0);

0 commit comments

Comments
 (0)