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