Merge tag 'for-linus-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
[platform/kernel/linux-rpi.git] / mm / damon / dbgfs-test.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * DAMON Debugfs Interface Unit Tests
4  *
5  * Author: SeongJae Park <sjpark@amazon.de>
6  */
7
8 #ifdef CONFIG_DAMON_DBGFS_KUNIT_TEST
9
10 #ifndef _DAMON_DBGFS_TEST_H
11 #define _DAMON_DBGFS_TEST_H
12
13 #include <kunit/test.h>
14
15 static void damon_dbgfs_test_str_to_ints(struct kunit *test)
16 {
17         char *question;
18         int *answers;
19         int expected[] = {12, 35, 46};
20         ssize_t nr_integers = 0, i;
21
22         question = "123";
23         answers = str_to_ints(question, strlen(question), &nr_integers);
24         KUNIT_EXPECT_EQ(test, (ssize_t)1, nr_integers);
25         KUNIT_EXPECT_EQ(test, 123, answers[0]);
26         kfree(answers);
27
28         question = "123abc";
29         answers = str_to_ints(question, strlen(question), &nr_integers);
30         KUNIT_EXPECT_EQ(test, (ssize_t)1, nr_integers);
31         KUNIT_EXPECT_EQ(test, 123, answers[0]);
32         kfree(answers);
33
34         question = "a123";
35         answers = str_to_ints(question, strlen(question), &nr_integers);
36         KUNIT_EXPECT_EQ(test, (ssize_t)0, nr_integers);
37         kfree(answers);
38
39         question = "12 35";
40         answers = str_to_ints(question, strlen(question), &nr_integers);
41         KUNIT_EXPECT_EQ(test, (ssize_t)2, nr_integers);
42         for (i = 0; i < nr_integers; i++)
43                 KUNIT_EXPECT_EQ(test, expected[i], answers[i]);
44         kfree(answers);
45
46         question = "12 35 46";
47         answers = str_to_ints(question, strlen(question), &nr_integers);
48         KUNIT_EXPECT_EQ(test, (ssize_t)3, nr_integers);
49         for (i = 0; i < nr_integers; i++)
50                 KUNIT_EXPECT_EQ(test, expected[i], answers[i]);
51         kfree(answers);
52
53         question = "12 35 abc 46";
54         answers = str_to_ints(question, strlen(question), &nr_integers);
55         KUNIT_EXPECT_EQ(test, (ssize_t)2, nr_integers);
56         for (i = 0; i < 2; i++)
57                 KUNIT_EXPECT_EQ(test, expected[i], answers[i]);
58         kfree(answers);
59
60         question = "";
61         answers = str_to_ints(question, strlen(question), &nr_integers);
62         KUNIT_EXPECT_EQ(test, (ssize_t)0, nr_integers);
63         kfree(answers);
64
65         question = "\n";
66         answers = str_to_ints(question, strlen(question), &nr_integers);
67         KUNIT_EXPECT_EQ(test, (ssize_t)0, nr_integers);
68         kfree(answers);
69 }
70
71 static void damon_dbgfs_test_set_targets(struct kunit *test)
72 {
73         struct damon_ctx *ctx = dbgfs_new_ctx();
74         char buf[64];
75
76         /* Make DAMON consider target has no pid */
77         damon_select_ops(ctx, DAMON_OPS_PADDR);
78
79         dbgfs_set_targets(ctx, 0, NULL);
80         sprint_target_ids(ctx, buf, 64);
81         KUNIT_EXPECT_STREQ(test, (char *)buf, "\n");
82
83         dbgfs_set_targets(ctx, 1, NULL);
84         sprint_target_ids(ctx, buf, 64);
85         KUNIT_EXPECT_STREQ(test, (char *)buf, "42\n");
86
87         dbgfs_set_targets(ctx, 0, NULL);
88         sprint_target_ids(ctx, buf, 64);
89         KUNIT_EXPECT_STREQ(test, (char *)buf, "\n");
90
91         dbgfs_destroy_ctx(ctx);
92 }
93
94 static void damon_dbgfs_test_set_init_regions(struct kunit *test)
95 {
96         struct damon_ctx *ctx = damon_new_ctx();
97         /* Each line represents one region in ``<target idx> <start> <end>`` */
98         char * const valid_inputs[] = {"1 10 20\n 1   20 30\n1 35 45",
99                 "1 10 20\n",
100                 "1 10 20\n0 39 59\n0 70 134\n  1  20 25\n",
101                 ""};
102         /* Reading the file again will show sorted, clean output */
103         char * const valid_expects[] = {"1 10 20\n1 20 30\n1 35 45\n",
104                 "1 10 20\n",
105                 "0 39 59\n0 70 134\n1 10 20\n1 20 25\n",
106                 ""};
107         char * const invalid_inputs[] = {"3 10 20\n",   /* target not exists */
108                 "1 10 20\n 1 14 26\n",          /* regions overlap */
109                 "0 10 20\n1 30 40\n 0 5 8"};    /* not sorted by address */
110         char *input, *expect;
111         int i, rc;
112         char buf[256];
113
114         damon_select_ops(ctx, DAMON_OPS_PADDR);
115
116         dbgfs_set_targets(ctx, 3, NULL);
117
118         /* Put valid inputs and check the results */
119         for (i = 0; i < ARRAY_SIZE(valid_inputs); i++) {
120                 input = valid_inputs[i];
121                 expect = valid_expects[i];
122
123                 rc = set_init_regions(ctx, input, strnlen(input, 256));
124                 KUNIT_EXPECT_EQ(test, rc, 0);
125
126                 memset(buf, 0, 256);
127                 sprint_init_regions(ctx, buf, 256);
128
129                 KUNIT_EXPECT_STREQ(test, (char *)buf, expect);
130         }
131         /* Put invalid inputs and check the return error code */
132         for (i = 0; i < ARRAY_SIZE(invalid_inputs); i++) {
133                 input = invalid_inputs[i];
134                 pr_info("input: %s\n", input);
135                 rc = set_init_regions(ctx, input, strnlen(input, 256));
136                 KUNIT_EXPECT_EQ(test, rc, -EINVAL);
137
138                 memset(buf, 0, 256);
139                 sprint_init_regions(ctx, buf, 256);
140
141                 KUNIT_EXPECT_STREQ(test, (char *)buf, "");
142         }
143
144         dbgfs_set_targets(ctx, 0, NULL);
145         damon_destroy_ctx(ctx);
146 }
147
148 static struct kunit_case damon_test_cases[] = {
149         KUNIT_CASE(damon_dbgfs_test_str_to_ints),
150         KUNIT_CASE(damon_dbgfs_test_set_targets),
151         KUNIT_CASE(damon_dbgfs_test_set_init_regions),
152         {},
153 };
154
155 static struct kunit_suite damon_test_suite = {
156         .name = "damon-dbgfs",
157         .test_cases = damon_test_cases,
158 };
159 kunit_test_suite(damon_test_suite);
160
161 #endif /* _DAMON_TEST_H */
162
163 #endif  /* CONFIG_DAMON_KUNIT_TEST */