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