117ccae8bSSeongJae Park /* SPDX-License-Identifier: GPL-2.0 */
217ccae8bSSeongJae Park /*
317ccae8bSSeongJae Park * Data Access Monitor Unit Tests
417ccae8bSSeongJae Park *
517ccae8bSSeongJae Park * Copyright 2019 Amazon.com, Inc. or its affiliates. All rights reserved.
617ccae8bSSeongJae Park *
717ccae8bSSeongJae Park * Author: SeongJae Park <sjpark@amazon.de>
817ccae8bSSeongJae Park */
917ccae8bSSeongJae Park
1017ccae8bSSeongJae Park #ifdef CONFIG_DAMON_KUNIT_TEST
1117ccae8bSSeongJae Park
1217ccae8bSSeongJae Park #ifndef _DAMON_CORE_TEST_H
1317ccae8bSSeongJae Park #define _DAMON_CORE_TEST_H
1417ccae8bSSeongJae Park
1517ccae8bSSeongJae Park #include <kunit/test.h>
1617ccae8bSSeongJae Park
damon_test_regions(struct kunit * test)1717ccae8bSSeongJae Park static void damon_test_regions(struct kunit *test)
1817ccae8bSSeongJae Park {
1917ccae8bSSeongJae Park struct damon_region *r;
2017ccae8bSSeongJae Park struct damon_target *t;
2117ccae8bSSeongJae Park
2217ccae8bSSeongJae Park r = damon_new_region(1, 2);
2317ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 1ul, r->ar.start);
2417ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 2ul, r->ar.end);
2517ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 0u, r->nr_accesses);
2617ccae8bSSeongJae Park
271971bd63SSeongJae Park t = damon_new_target();
2817ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 0u, damon_nr_regions(t));
2917ccae8bSSeongJae Park
3017ccae8bSSeongJae Park damon_add_region(r, t);
3117ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 1u, damon_nr_regions(t));
3217ccae8bSSeongJae Park
3317ccae8bSSeongJae Park damon_del_region(r, t);
3417ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 0u, damon_nr_regions(t));
3517ccae8bSSeongJae Park
3617ccae8bSSeongJae Park damon_free_target(t);
3717ccae8bSSeongJae Park }
3817ccae8bSSeongJae Park
nr_damon_targets(struct damon_ctx * ctx)3917ccae8bSSeongJae Park static unsigned int nr_damon_targets(struct damon_ctx *ctx)
4017ccae8bSSeongJae Park {
4117ccae8bSSeongJae Park struct damon_target *t;
4217ccae8bSSeongJae Park unsigned int nr_targets = 0;
4317ccae8bSSeongJae Park
4417ccae8bSSeongJae Park damon_for_each_target(t, ctx)
4517ccae8bSSeongJae Park nr_targets++;
4617ccae8bSSeongJae Park
4717ccae8bSSeongJae Park return nr_targets;
4817ccae8bSSeongJae Park }
4917ccae8bSSeongJae Park
damon_test_target(struct kunit * test)5017ccae8bSSeongJae Park static void damon_test_target(struct kunit *test)
5117ccae8bSSeongJae Park {
5217ccae8bSSeongJae Park struct damon_ctx *c = damon_new_ctx();
5317ccae8bSSeongJae Park struct damon_target *t;
5417ccae8bSSeongJae Park
551971bd63SSeongJae Park t = damon_new_target();
5617ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 0u, nr_damon_targets(c));
5717ccae8bSSeongJae Park
5817ccae8bSSeongJae Park damon_add_target(c, t);
5917ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 1u, nr_damon_targets(c));
6017ccae8bSSeongJae Park
6117ccae8bSSeongJae Park damon_destroy_target(t);
6217ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 0u, nr_damon_targets(c));
6317ccae8bSSeongJae Park
6417ccae8bSSeongJae Park damon_destroy_ctx(c);
6517ccae8bSSeongJae Park }
6617ccae8bSSeongJae Park
6717ccae8bSSeongJae Park /*
6817ccae8bSSeongJae Park * Test kdamond_reset_aggregated()
6917ccae8bSSeongJae Park *
7017ccae8bSSeongJae Park * DAMON checks access to each region and aggregates this information as the
7117ccae8bSSeongJae Park * access frequency of each region. In detail, it increases '->nr_accesses' of
7217ccae8bSSeongJae Park * regions that an access has confirmed. 'kdamond_reset_aggregated()' flushes
7317ccae8bSSeongJae Park * the aggregated information ('->nr_accesses' of each regions) to the result
7417ccae8bSSeongJae Park * buffer. As a result of the flushing, the '->nr_accesses' of regions are
7517ccae8bSSeongJae Park * initialized to zero.
7617ccae8bSSeongJae Park */
damon_test_aggregate(struct kunit * test)7717ccae8bSSeongJae Park static void damon_test_aggregate(struct kunit *test)
7817ccae8bSSeongJae Park {
7917ccae8bSSeongJae Park struct damon_ctx *ctx = damon_new_ctx();
8017ccae8bSSeongJae Park unsigned long saddr[][3] = {{10, 20, 30}, {5, 42, 49}, {13, 33, 55} };
8117ccae8bSSeongJae Park unsigned long eaddr[][3] = {{15, 27, 40}, {31, 45, 55}, {23, 44, 66} };
8217ccae8bSSeongJae Park unsigned long accesses[][3] = {{42, 95, 84}, {10, 20, 30}, {0, 1, 2} };
8317ccae8bSSeongJae Park struct damon_target *t;
8417ccae8bSSeongJae Park struct damon_region *r;
8517ccae8bSSeongJae Park int it, ir;
8617ccae8bSSeongJae Park
8743642825SSeongJae Park for (it = 0; it < 3; it++) {
881971bd63SSeongJae Park t = damon_new_target();
8943642825SSeongJae Park damon_add_target(ctx, t);
9043642825SSeongJae Park }
9117ccae8bSSeongJae Park
9217ccae8bSSeongJae Park it = 0;
9317ccae8bSSeongJae Park damon_for_each_target(t, ctx) {
9417ccae8bSSeongJae Park for (ir = 0; ir < 3; ir++) {
9517ccae8bSSeongJae Park r = damon_new_region(saddr[it][ir], eaddr[it][ir]);
9617ccae8bSSeongJae Park r->nr_accesses = accesses[it][ir];
9717ccae8bSSeongJae Park damon_add_region(r, t);
9817ccae8bSSeongJae Park }
9917ccae8bSSeongJae Park it++;
10017ccae8bSSeongJae Park }
10117ccae8bSSeongJae Park kdamond_reset_aggregated(ctx);
10217ccae8bSSeongJae Park it = 0;
10317ccae8bSSeongJae Park damon_for_each_target(t, ctx) {
10417ccae8bSSeongJae Park ir = 0;
10517ccae8bSSeongJae Park /* '->nr_accesses' should be zeroed */
10617ccae8bSSeongJae Park damon_for_each_region(r, t) {
10717ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 0u, r->nr_accesses);
10817ccae8bSSeongJae Park ir++;
10917ccae8bSSeongJae Park }
11017ccae8bSSeongJae Park /* regions should be preserved */
11117ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 3, ir);
11217ccae8bSSeongJae Park it++;
11317ccae8bSSeongJae Park }
11417ccae8bSSeongJae Park /* targets also should be preserved */
11517ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, 3, it);
11617ccae8bSSeongJae Park
11717ccae8bSSeongJae Park damon_destroy_ctx(ctx);
11817ccae8bSSeongJae Park }
11917ccae8bSSeongJae Park
damon_test_split_at(struct kunit * test)12017ccae8bSSeongJae Park static void damon_test_split_at(struct kunit *test)
12117ccae8bSSeongJae Park {
12217ccae8bSSeongJae Park struct damon_ctx *c = damon_new_ctx();
12317ccae8bSSeongJae Park struct damon_target *t;
12417ccae8bSSeongJae Park struct damon_region *r;
12517ccae8bSSeongJae Park
1261971bd63SSeongJae Park t = damon_new_target();
12717ccae8bSSeongJae Park r = damon_new_region(0, 100);
12817ccae8bSSeongJae Park damon_add_region(r, t);
1294ed98243SKaixu Xia damon_split_region_at(t, r, 25);
13017ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.start, 0ul);
13117ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.end, 25ul);
13217ccae8bSSeongJae Park
13317ccae8bSSeongJae Park r = damon_next_region(r);
13417ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.start, 25ul);
13517ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.end, 100ul);
13617ccae8bSSeongJae Park
13717ccae8bSSeongJae Park damon_free_target(t);
13817ccae8bSSeongJae Park damon_destroy_ctx(c);
13917ccae8bSSeongJae Park }
14017ccae8bSSeongJae Park
damon_test_merge_two(struct kunit * test)14117ccae8bSSeongJae Park static void damon_test_merge_two(struct kunit *test)
14217ccae8bSSeongJae Park {
14317ccae8bSSeongJae Park struct damon_target *t;
14417ccae8bSSeongJae Park struct damon_region *r, *r2, *r3;
14517ccae8bSSeongJae Park int i;
14617ccae8bSSeongJae Park
1471971bd63SSeongJae Park t = damon_new_target();
14817ccae8bSSeongJae Park r = damon_new_region(0, 100);
14917ccae8bSSeongJae Park r->nr_accesses = 10;
15017ccae8bSSeongJae Park damon_add_region(r, t);
15117ccae8bSSeongJae Park r2 = damon_new_region(100, 300);
15217ccae8bSSeongJae Park r2->nr_accesses = 20;
15317ccae8bSSeongJae Park damon_add_region(r2, t);
15417ccae8bSSeongJae Park
15517ccae8bSSeongJae Park damon_merge_two_regions(t, r, r2);
15617ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.start, 0ul);
15717ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.end, 300ul);
15817ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->nr_accesses, 16u);
15917ccae8bSSeongJae Park
16017ccae8bSSeongJae Park i = 0;
16117ccae8bSSeongJae Park damon_for_each_region(r3, t) {
16217ccae8bSSeongJae Park KUNIT_EXPECT_PTR_EQ(test, r, r3);
16317ccae8bSSeongJae Park i++;
16417ccae8bSSeongJae Park }
16517ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, i, 1);
16617ccae8bSSeongJae Park
16717ccae8bSSeongJae Park damon_free_target(t);
16817ccae8bSSeongJae Park }
16917ccae8bSSeongJae Park
__nth_region_of(struct damon_target * t,int idx)17017ccae8bSSeongJae Park static struct damon_region *__nth_region_of(struct damon_target *t, int idx)
17117ccae8bSSeongJae Park {
17217ccae8bSSeongJae Park struct damon_region *r;
17317ccae8bSSeongJae Park unsigned int i = 0;
17417ccae8bSSeongJae Park
17517ccae8bSSeongJae Park damon_for_each_region(r, t) {
17617ccae8bSSeongJae Park if (i++ == idx)
17717ccae8bSSeongJae Park return r;
17817ccae8bSSeongJae Park }
17917ccae8bSSeongJae Park
18017ccae8bSSeongJae Park return NULL;
18117ccae8bSSeongJae Park }
18217ccae8bSSeongJae Park
damon_test_merge_regions_of(struct kunit * test)18317ccae8bSSeongJae Park static void damon_test_merge_regions_of(struct kunit *test)
18417ccae8bSSeongJae Park {
18517ccae8bSSeongJae Park struct damon_target *t;
18617ccae8bSSeongJae Park struct damon_region *r;
18717ccae8bSSeongJae Park unsigned long sa[] = {0, 100, 114, 122, 130, 156, 170, 184};
18817ccae8bSSeongJae Park unsigned long ea[] = {100, 112, 122, 130, 156, 170, 184, 230};
18917ccae8bSSeongJae Park unsigned int nrs[] = {0, 0, 10, 10, 20, 30, 1, 2};
19017ccae8bSSeongJae Park
19117ccae8bSSeongJae Park unsigned long saddrs[] = {0, 114, 130, 156, 170};
19217ccae8bSSeongJae Park unsigned long eaddrs[] = {112, 130, 156, 170, 230};
19317ccae8bSSeongJae Park int i;
19417ccae8bSSeongJae Park
1951971bd63SSeongJae Park t = damon_new_target();
19617ccae8bSSeongJae Park for (i = 0; i < ARRAY_SIZE(sa); i++) {
19717ccae8bSSeongJae Park r = damon_new_region(sa[i], ea[i]);
19817ccae8bSSeongJae Park r->nr_accesses = nrs[i];
19917ccae8bSSeongJae Park damon_add_region(r, t);
20017ccae8bSSeongJae Park }
20117ccae8bSSeongJae Park
20217ccae8bSSeongJae Park damon_merge_regions_of(t, 9, 9999);
20317ccae8bSSeongJae Park /* 0-112, 114-130, 130-156, 156-170 */
20417ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 5u);
20517ccae8bSSeongJae Park for (i = 0; i < 5; i++) {
20617ccae8bSSeongJae Park r = __nth_region_of(t, i);
20717ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.start, saddrs[i]);
20817ccae8bSSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.end, eaddrs[i]);
20917ccae8bSSeongJae Park }
21017ccae8bSSeongJae Park damon_free_target(t);
21117ccae8bSSeongJae Park }
21217ccae8bSSeongJae Park
damon_test_split_regions_of(struct kunit * test)21317ccae8bSSeongJae Park static void damon_test_split_regions_of(struct kunit *test)
21417ccae8bSSeongJae Park {
21517ccae8bSSeongJae Park struct damon_ctx *c = damon_new_ctx();
21617ccae8bSSeongJae Park struct damon_target *t;
21717ccae8bSSeongJae Park struct damon_region *r;
21817ccae8bSSeongJae Park
2191971bd63SSeongJae Park t = damon_new_target();
22017ccae8bSSeongJae Park r = damon_new_region(0, 22);
22117ccae8bSSeongJae Park damon_add_region(r, t);
2224ed98243SKaixu Xia damon_split_regions_of(t, 2);
2232e014660SSeongJae Park KUNIT_EXPECT_LE(test, damon_nr_regions(t), 2u);
22417ccae8bSSeongJae Park damon_free_target(t);
22517ccae8bSSeongJae Park
2261971bd63SSeongJae Park t = damon_new_target();
22717ccae8bSSeongJae Park r = damon_new_region(0, 220);
22817ccae8bSSeongJae Park damon_add_region(r, t);
2294ed98243SKaixu Xia damon_split_regions_of(t, 4);
2302e014660SSeongJae Park KUNIT_EXPECT_LE(test, damon_nr_regions(t), 4u);
23117ccae8bSSeongJae Park damon_free_target(t);
23217ccae8bSSeongJae Park damon_destroy_ctx(c);
23317ccae8bSSeongJae Park }
23417ccae8bSSeongJae Park
damon_test_ops_registration(struct kunit * test)2354f540f5aSSeongJae Park static void damon_test_ops_registration(struct kunit *test)
2364f540f5aSSeongJae Park {
2374f540f5aSSeongJae Park struct damon_ctx *c = damon_new_ctx();
2384f540f5aSSeongJae Park struct damon_operations ops, bak;
2394f540f5aSSeongJae Park
2404f540f5aSSeongJae Park /* DAMON_OPS_{V,P}ADDR are registered on subsys_initcall */
2414f540f5aSSeongJae Park KUNIT_EXPECT_EQ(test, damon_select_ops(c, DAMON_OPS_VADDR), 0);
2424f540f5aSSeongJae Park KUNIT_EXPECT_EQ(test, damon_select_ops(c, DAMON_OPS_PADDR), 0);
2434f540f5aSSeongJae Park
2444f540f5aSSeongJae Park /* Double-registration is prohibited */
2454f540f5aSSeongJae Park ops.id = DAMON_OPS_VADDR;
2464f540f5aSSeongJae Park KUNIT_EXPECT_EQ(test, damon_register_ops(&ops), -EINVAL);
2474f540f5aSSeongJae Park ops.id = DAMON_OPS_PADDR;
2484f540f5aSSeongJae Park KUNIT_EXPECT_EQ(test, damon_register_ops(&ops), -EINVAL);
2494f540f5aSSeongJae Park
2504f540f5aSSeongJae Park /* Unknown ops id cannot be registered */
2514f540f5aSSeongJae Park KUNIT_EXPECT_EQ(test, damon_select_ops(c, NR_DAMON_OPS), -EINVAL);
2524f540f5aSSeongJae Park
2534f540f5aSSeongJae Park /* Registration should success after unregistration */
2544f540f5aSSeongJae Park mutex_lock(&damon_ops_lock);
2554f540f5aSSeongJae Park bak = damon_registered_ops[DAMON_OPS_VADDR];
2564f540f5aSSeongJae Park damon_registered_ops[DAMON_OPS_VADDR] = (struct damon_operations){};
2574f540f5aSSeongJae Park mutex_unlock(&damon_ops_lock);
2584f540f5aSSeongJae Park
2594f540f5aSSeongJae Park ops.id = DAMON_OPS_VADDR;
2604f540f5aSSeongJae Park KUNIT_EXPECT_EQ(test, damon_register_ops(&ops), 0);
2614f540f5aSSeongJae Park
2624f540f5aSSeongJae Park mutex_lock(&damon_ops_lock);
2634f540f5aSSeongJae Park damon_registered_ops[DAMON_OPS_VADDR] = bak;
2644f540f5aSSeongJae Park mutex_unlock(&damon_ops_lock);
2654f540f5aSSeongJae Park
2664f540f5aSSeongJae Park /* Check double-registration failure again */
2674f540f5aSSeongJae Park KUNIT_EXPECT_EQ(test, damon_register_ops(&ops), -EINVAL);
2684f540f5aSSeongJae Park }
2694f540f5aSSeongJae Park
damon_test_set_regions(struct kunit * test)27062f40956SSeongJae Park static void damon_test_set_regions(struct kunit *test)
27162f40956SSeongJae Park {
27262f40956SSeongJae Park struct damon_target *t = damon_new_target();
27362f40956SSeongJae Park struct damon_region *r1 = damon_new_region(4, 16);
27462f40956SSeongJae Park struct damon_region *r2 = damon_new_region(24, 32);
27562f40956SSeongJae Park struct damon_addr_range range = {.start = 8, .end = 28};
27662f40956SSeongJae Park unsigned long expects[] = {8, 16, 16, 24, 24, 28};
27762f40956SSeongJae Park int expect_idx = 0;
27862f40956SSeongJae Park struct damon_region *r;
27962f40956SSeongJae Park
28062f40956SSeongJae Park damon_add_region(r1, t);
28162f40956SSeongJae Park damon_add_region(r2, t);
28262f40956SSeongJae Park damon_set_regions(t, &range, 1);
28362f40956SSeongJae Park
28462f40956SSeongJae Park KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 3);
28562f40956SSeongJae Park damon_for_each_region(r, t) {
28662f40956SSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.start, expects[expect_idx++]);
28762f40956SSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.end, expects[expect_idx++]);
28862f40956SSeongJae Park }
28962f40956SSeongJae Park damon_destroy_target(t);
29062f40956SSeongJae Park }
29162f40956SSeongJae Park
damon_test_update_monitoring_result(struct kunit * test)292f4c978b6SSeongJae Park static void damon_test_update_monitoring_result(struct kunit *test)
293f4c978b6SSeongJae Park {
294f4c978b6SSeongJae Park struct damon_attrs old_attrs = {
295f4c978b6SSeongJae Park .sample_interval = 10, .aggr_interval = 1000,};
296f4c978b6SSeongJae Park struct damon_attrs new_attrs;
297f4c978b6SSeongJae Park struct damon_region *r = damon_new_region(3, 7);
298f4c978b6SSeongJae Park
299f4c978b6SSeongJae Park r->nr_accesses = 15;
300f4c978b6SSeongJae Park r->age = 20;
301f4c978b6SSeongJae Park
302f4c978b6SSeongJae Park new_attrs = (struct damon_attrs){
303f4c978b6SSeongJae Park .sample_interval = 100, .aggr_interval = 10000,};
304f4c978b6SSeongJae Park damon_update_monitoring_result(r, &old_attrs, &new_attrs);
305f4c978b6SSeongJae Park KUNIT_EXPECT_EQ(test, r->nr_accesses, 15);
306f4c978b6SSeongJae Park KUNIT_EXPECT_EQ(test, r->age, 2);
307f4c978b6SSeongJae Park
308f4c978b6SSeongJae Park new_attrs = (struct damon_attrs){
309f4c978b6SSeongJae Park .sample_interval = 1, .aggr_interval = 1000};
310f4c978b6SSeongJae Park damon_update_monitoring_result(r, &old_attrs, &new_attrs);
311f4c978b6SSeongJae Park KUNIT_EXPECT_EQ(test, r->nr_accesses, 150);
312f4c978b6SSeongJae Park KUNIT_EXPECT_EQ(test, r->age, 2);
313f4c978b6SSeongJae Park
314f4c978b6SSeongJae Park new_attrs = (struct damon_attrs){
315f4c978b6SSeongJae Park .sample_interval = 1, .aggr_interval = 100};
316f4c978b6SSeongJae Park damon_update_monitoring_result(r, &old_attrs, &new_attrs);
317f4c978b6SSeongJae Park KUNIT_EXPECT_EQ(test, r->nr_accesses, 150);
318f4c978b6SSeongJae Park KUNIT_EXPECT_EQ(test, r->age, 20);
319f4c978b6SSeongJae Park }
320f4c978b6SSeongJae Park
damon_test_set_attrs(struct kunit * test)321aa13779bSSeongJae Park static void damon_test_set_attrs(struct kunit *test)
322aa13779bSSeongJae Park {
323d1836a3bSFeng Tang struct damon_ctx *c = damon_new_ctx();
324aa13779bSSeongJae Park struct damon_attrs valid_attrs = {
325aa13779bSSeongJae Park .min_nr_regions = 10, .max_nr_regions = 1000,
326aa13779bSSeongJae Park .sample_interval = 5000, .aggr_interval = 100000,};
327aa13779bSSeongJae Park struct damon_attrs invalid_attrs;
328aa13779bSSeongJae Park
329d1836a3bSFeng Tang KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &valid_attrs), 0);
330aa13779bSSeongJae Park
331aa13779bSSeongJae Park invalid_attrs = valid_attrs;
332aa13779bSSeongJae Park invalid_attrs.min_nr_regions = 1;
333d1836a3bSFeng Tang KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &invalid_attrs), -EINVAL);
334aa13779bSSeongJae Park
335aa13779bSSeongJae Park invalid_attrs = valid_attrs;
336aa13779bSSeongJae Park invalid_attrs.max_nr_regions = 9;
337d1836a3bSFeng Tang KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &invalid_attrs), -EINVAL);
338aa13779bSSeongJae Park
339aa13779bSSeongJae Park invalid_attrs = valid_attrs;
340aa13779bSSeongJae Park invalid_attrs.aggr_interval = 4999;
341d1836a3bSFeng Tang KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &invalid_attrs), -EINVAL);
342aa13779bSSeongJae Park }
343aa13779bSSeongJae Park
damos_test_new_filter(struct kunit * test)3442a158e95SSeongJae Park static void damos_test_new_filter(struct kunit *test)
3452a158e95SSeongJae Park {
3462a158e95SSeongJae Park struct damos_filter *filter;
3472a158e95SSeongJae Park
3482a158e95SSeongJae Park filter = damos_new_filter(DAMOS_FILTER_TYPE_ANON, true);
3492a158e95SSeongJae Park KUNIT_EXPECT_EQ(test, filter->type, DAMOS_FILTER_TYPE_ANON);
3502a158e95SSeongJae Park KUNIT_EXPECT_EQ(test, filter->matching, true);
3512a158e95SSeongJae Park KUNIT_EXPECT_PTR_EQ(test, filter->list.prev, &filter->list);
3522a158e95SSeongJae Park KUNIT_EXPECT_PTR_EQ(test, filter->list.next, &filter->list);
3532a158e95SSeongJae Park damos_destroy_filter(filter);
3542a158e95SSeongJae Park }
3552a158e95SSeongJae Park
damos_test_filter_out(struct kunit * test)356*26713c89SSeongJae Park static void damos_test_filter_out(struct kunit *test)
357*26713c89SSeongJae Park {
358*26713c89SSeongJae Park struct damon_target *t;
359*26713c89SSeongJae Park struct damon_region *r, *r2;
360*26713c89SSeongJae Park struct damos_filter *f;
361*26713c89SSeongJae Park
362*26713c89SSeongJae Park f = damos_new_filter(DAMOS_FILTER_TYPE_ADDR, true);
363*26713c89SSeongJae Park f->addr_range = (struct damon_addr_range){
364*26713c89SSeongJae Park .start = DAMON_MIN_REGION * 2, .end = DAMON_MIN_REGION * 6};
365*26713c89SSeongJae Park
366*26713c89SSeongJae Park t = damon_new_target();
367*26713c89SSeongJae Park r = damon_new_region(DAMON_MIN_REGION * 3, DAMON_MIN_REGION * 5);
368*26713c89SSeongJae Park damon_add_region(r, t);
369*26713c89SSeongJae Park
370*26713c89SSeongJae Park /* region in the range */
371*26713c89SSeongJae Park KUNIT_EXPECT_TRUE(test, __damos_filter_out(NULL, t, r, f));
372*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
373*26713c89SSeongJae Park
374*26713c89SSeongJae Park /* region before the range */
375*26713c89SSeongJae Park r->ar.start = DAMON_MIN_REGION * 1;
376*26713c89SSeongJae Park r->ar.end = DAMON_MIN_REGION * 2;
377*26713c89SSeongJae Park KUNIT_EXPECT_FALSE(test, __damos_filter_out(NULL, t, r, f));
378*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
379*26713c89SSeongJae Park
380*26713c89SSeongJae Park /* region after the range */
381*26713c89SSeongJae Park r->ar.start = DAMON_MIN_REGION * 6;
382*26713c89SSeongJae Park r->ar.end = DAMON_MIN_REGION * 8;
383*26713c89SSeongJae Park KUNIT_EXPECT_FALSE(test, __damos_filter_out(NULL, t, r, f));
384*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
385*26713c89SSeongJae Park
386*26713c89SSeongJae Park /* region started before the range */
387*26713c89SSeongJae Park r->ar.start = DAMON_MIN_REGION * 1;
388*26713c89SSeongJae Park r->ar.end = DAMON_MIN_REGION * 4;
389*26713c89SSeongJae Park KUNIT_EXPECT_FALSE(test, __damos_filter_out(NULL, t, r, f));
390*26713c89SSeongJae Park /* filter should have split the region */
391*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.start, DAMON_MIN_REGION * 1);
392*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.end, DAMON_MIN_REGION * 2);
393*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 2);
394*26713c89SSeongJae Park r2 = damon_next_region(r);
395*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, r2->ar.start, DAMON_MIN_REGION * 2);
396*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, r2->ar.end, DAMON_MIN_REGION * 4);
397*26713c89SSeongJae Park damon_destroy_region(r2, t);
398*26713c89SSeongJae Park
399*26713c89SSeongJae Park /* region started in the range */
400*26713c89SSeongJae Park r->ar.start = DAMON_MIN_REGION * 2;
401*26713c89SSeongJae Park r->ar.end = DAMON_MIN_REGION * 8;
402*26713c89SSeongJae Park KUNIT_EXPECT_TRUE(test, __damos_filter_out(NULL, t, r, f));
403*26713c89SSeongJae Park /* filter should have split the region */
404*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.start, DAMON_MIN_REGION * 2);
405*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, r->ar.end, DAMON_MIN_REGION * 6);
406*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 2);
407*26713c89SSeongJae Park r2 = damon_next_region(r);
408*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, r2->ar.start, DAMON_MIN_REGION * 6);
409*26713c89SSeongJae Park KUNIT_EXPECT_EQ(test, r2->ar.end, DAMON_MIN_REGION * 8);
410*26713c89SSeongJae Park damon_destroy_region(r2, t);
411*26713c89SSeongJae Park
412*26713c89SSeongJae Park damon_free_target(t);
413*26713c89SSeongJae Park damos_free_filter(f);
414*26713c89SSeongJae Park }
415*26713c89SSeongJae Park
41617ccae8bSSeongJae Park static struct kunit_case damon_test_cases[] = {
41717ccae8bSSeongJae Park KUNIT_CASE(damon_test_target),
41817ccae8bSSeongJae Park KUNIT_CASE(damon_test_regions),
41917ccae8bSSeongJae Park KUNIT_CASE(damon_test_aggregate),
42017ccae8bSSeongJae Park KUNIT_CASE(damon_test_split_at),
42117ccae8bSSeongJae Park KUNIT_CASE(damon_test_merge_two),
42217ccae8bSSeongJae Park KUNIT_CASE(damon_test_merge_regions_of),
42317ccae8bSSeongJae Park KUNIT_CASE(damon_test_split_regions_of),
4244f540f5aSSeongJae Park KUNIT_CASE(damon_test_ops_registration),
42562f40956SSeongJae Park KUNIT_CASE(damon_test_set_regions),
426f4c978b6SSeongJae Park KUNIT_CASE(damon_test_update_monitoring_result),
427aa13779bSSeongJae Park KUNIT_CASE(damon_test_set_attrs),
4282a158e95SSeongJae Park KUNIT_CASE(damos_test_new_filter),
429*26713c89SSeongJae Park KUNIT_CASE(damos_test_filter_out),
43017ccae8bSSeongJae Park {},
43117ccae8bSSeongJae Park };
43217ccae8bSSeongJae Park
43317ccae8bSSeongJae Park static struct kunit_suite damon_test_suite = {
43417ccae8bSSeongJae Park .name = "damon",
43517ccae8bSSeongJae Park .test_cases = damon_test_cases,
43617ccae8bSSeongJae Park };
43717ccae8bSSeongJae Park kunit_test_suite(damon_test_suite);
43817ccae8bSSeongJae Park
43917ccae8bSSeongJae Park #endif /* _DAMON_CORE_TEST_H */
44017ccae8bSSeongJae Park
44117ccae8bSSeongJae Park #endif /* CONFIG_DAMON_KUNIT_TEST */
442