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