162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * DAMON Debugfs Interface Unit Tests 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: SeongJae Park <sjpark@amazon.de> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifdef CONFIG_DAMON_DBGFS_KUNIT_TEST 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef _DAMON_DBGFS_TEST_H 1162306a36Sopenharmony_ci#define _DAMON_DBGFS_TEST_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <kunit/test.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic void damon_dbgfs_test_str_to_ints(struct kunit *test) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci char *question; 1862306a36Sopenharmony_ci int *answers; 1962306a36Sopenharmony_ci int expected[] = {12, 35, 46}; 2062306a36Sopenharmony_ci ssize_t nr_integers = 0, i; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci question = "123"; 2362306a36Sopenharmony_ci answers = str_to_ints(question, strlen(question), &nr_integers); 2462306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, (ssize_t)1, nr_integers); 2562306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, 123, answers[0]); 2662306a36Sopenharmony_ci kfree(answers); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci question = "123abc"; 2962306a36Sopenharmony_ci answers = str_to_ints(question, strlen(question), &nr_integers); 3062306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, (ssize_t)1, nr_integers); 3162306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, 123, answers[0]); 3262306a36Sopenharmony_ci kfree(answers); 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci question = "a123"; 3562306a36Sopenharmony_ci answers = str_to_ints(question, strlen(question), &nr_integers); 3662306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, (ssize_t)0, nr_integers); 3762306a36Sopenharmony_ci kfree(answers); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci question = "12 35"; 4062306a36Sopenharmony_ci answers = str_to_ints(question, strlen(question), &nr_integers); 4162306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, (ssize_t)2, nr_integers); 4262306a36Sopenharmony_ci for (i = 0; i < nr_integers; i++) 4362306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, expected[i], answers[i]); 4462306a36Sopenharmony_ci kfree(answers); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci question = "12 35 46"; 4762306a36Sopenharmony_ci answers = str_to_ints(question, strlen(question), &nr_integers); 4862306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, (ssize_t)3, nr_integers); 4962306a36Sopenharmony_ci for (i = 0; i < nr_integers; i++) 5062306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, expected[i], answers[i]); 5162306a36Sopenharmony_ci kfree(answers); 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci question = "12 35 abc 46"; 5462306a36Sopenharmony_ci answers = str_to_ints(question, strlen(question), &nr_integers); 5562306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, (ssize_t)2, nr_integers); 5662306a36Sopenharmony_ci for (i = 0; i < 2; i++) 5762306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, expected[i], answers[i]); 5862306a36Sopenharmony_ci kfree(answers); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci question = ""; 6162306a36Sopenharmony_ci answers = str_to_ints(question, strlen(question), &nr_integers); 6262306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, (ssize_t)0, nr_integers); 6362306a36Sopenharmony_ci kfree(answers); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci question = "\n"; 6662306a36Sopenharmony_ci answers = str_to_ints(question, strlen(question), &nr_integers); 6762306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, (ssize_t)0, nr_integers); 6862306a36Sopenharmony_ci kfree(answers); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic void damon_dbgfs_test_set_targets(struct kunit *test) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci struct damon_ctx *ctx = dbgfs_new_ctx(); 7462306a36Sopenharmony_ci char buf[64]; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci /* Make DAMON consider target has no pid */ 7762306a36Sopenharmony_ci damon_select_ops(ctx, DAMON_OPS_PADDR); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci dbgfs_set_targets(ctx, 0, NULL); 8062306a36Sopenharmony_ci sprint_target_ids(ctx, buf, 64); 8162306a36Sopenharmony_ci KUNIT_EXPECT_STREQ(test, (char *)buf, "\n"); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci dbgfs_set_targets(ctx, 1, NULL); 8462306a36Sopenharmony_ci sprint_target_ids(ctx, buf, 64); 8562306a36Sopenharmony_ci KUNIT_EXPECT_STREQ(test, (char *)buf, "42\n"); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci dbgfs_set_targets(ctx, 0, NULL); 8862306a36Sopenharmony_ci sprint_target_ids(ctx, buf, 64); 8962306a36Sopenharmony_ci KUNIT_EXPECT_STREQ(test, (char *)buf, "\n"); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci dbgfs_destroy_ctx(ctx); 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic void damon_dbgfs_test_set_init_regions(struct kunit *test) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci struct damon_ctx *ctx = damon_new_ctx(); 9762306a36Sopenharmony_ci /* Each line represents one region in ``<target idx> <start> <end>`` */ 9862306a36Sopenharmony_ci char * const valid_inputs[] = {"1 10 20\n 1 20 30\n1 35 45", 9962306a36Sopenharmony_ci "1 10 20\n", 10062306a36Sopenharmony_ci "1 10 20\n0 39 59\n0 70 134\n 1 20 25\n", 10162306a36Sopenharmony_ci ""}; 10262306a36Sopenharmony_ci /* Reading the file again will show sorted, clean output */ 10362306a36Sopenharmony_ci char * const valid_expects[] = {"1 10 20\n1 20 30\n1 35 45\n", 10462306a36Sopenharmony_ci "1 10 20\n", 10562306a36Sopenharmony_ci "0 39 59\n0 70 134\n1 10 20\n1 20 25\n", 10662306a36Sopenharmony_ci ""}; 10762306a36Sopenharmony_ci char * const invalid_inputs[] = {"3 10 20\n", /* target not exists */ 10862306a36Sopenharmony_ci "1 10 20\n 1 14 26\n", /* regions overlap */ 10962306a36Sopenharmony_ci "0 10 20\n1 30 40\n 0 5 8"}; /* not sorted by address */ 11062306a36Sopenharmony_ci char *input, *expect; 11162306a36Sopenharmony_ci int i, rc; 11262306a36Sopenharmony_ci char buf[256]; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci damon_select_ops(ctx, DAMON_OPS_PADDR); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci dbgfs_set_targets(ctx, 3, NULL); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci /* Put valid inputs and check the results */ 11962306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(valid_inputs); i++) { 12062306a36Sopenharmony_ci input = valid_inputs[i]; 12162306a36Sopenharmony_ci expect = valid_expects[i]; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci rc = set_init_regions(ctx, input, strnlen(input, 256)); 12462306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, rc, 0); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci memset(buf, 0, 256); 12762306a36Sopenharmony_ci sprint_init_regions(ctx, buf, 256); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci KUNIT_EXPECT_STREQ(test, (char *)buf, expect); 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci /* Put invalid inputs and check the return error code */ 13262306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(invalid_inputs); i++) { 13362306a36Sopenharmony_ci input = invalid_inputs[i]; 13462306a36Sopenharmony_ci pr_info("input: %s\n", input); 13562306a36Sopenharmony_ci rc = set_init_regions(ctx, input, strnlen(input, 256)); 13662306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, rc, -EINVAL); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci memset(buf, 0, 256); 13962306a36Sopenharmony_ci sprint_init_regions(ctx, buf, 256); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci KUNIT_EXPECT_STREQ(test, (char *)buf, ""); 14262306a36Sopenharmony_ci } 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci dbgfs_set_targets(ctx, 0, NULL); 14562306a36Sopenharmony_ci damon_destroy_ctx(ctx); 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic struct kunit_case damon_test_cases[] = { 14962306a36Sopenharmony_ci KUNIT_CASE(damon_dbgfs_test_str_to_ints), 15062306a36Sopenharmony_ci KUNIT_CASE(damon_dbgfs_test_set_targets), 15162306a36Sopenharmony_ci KUNIT_CASE(damon_dbgfs_test_set_init_regions), 15262306a36Sopenharmony_ci {}, 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic struct kunit_suite damon_test_suite = { 15662306a36Sopenharmony_ci .name = "damon-dbgfs", 15762306a36Sopenharmony_ci .test_cases = damon_test_cases, 15862306a36Sopenharmony_ci}; 15962306a36Sopenharmony_cikunit_test_suite(damon_test_suite); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci#endif /* _DAMON_TEST_H */ 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci#endif /* CONFIG_DAMON_KUNIT_TEST */ 164