| From: SeongJae Park <sj@kernel.org> |
| Subject: selftests/damon: add python and drgn-based DAMON sysfs test |
| Date: Sat, 28 Jun 2025 09:04:25 -0700 |
| |
| Add a python-written DAMON sysfs functionality selftest. It sets DAMON |
| parameters using Python module _damon_sysfs, reads updated kernel internal |
| DAMON status and parameters using a 'drgn' script, namely |
| drgn_dump_damon_status.py, and compare if the resulted DAMON internal |
| status is as expected. The test is very minimum at the moment. |
| |
| Link: https://lkml.kernel.org/r/20250628160428.53115-4-sj@kernel.org |
| Signed-off-by: SeongJae Park <sj@kernel.org> |
| Cc: Shuah Khan <shuah@kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| tools/testing/selftests/damon/Makefile | 1 |
| tools/testing/selftests/damon/sysfs.py | 42 +++++++++++++++++++++++ |
| 2 files changed, 43 insertions(+) |
| |
| --- a/tools/testing/selftests/damon/Makefile~selftests-damon-add-python-and-drgn-based-damon-sysfs-test |
| +++ a/tools/testing/selftests/damon/Makefile |
| @@ -7,6 +7,7 @@ TEST_FILES = _damon_sysfs.py |
| |
| # functionality tests |
| TEST_PROGS += sysfs.sh |
| +TEST_PROGS += sysfs.py |
| TEST_PROGS += sysfs_update_schemes_tried_regions_wss_estimation.py |
| TEST_PROGS += damos_quota.py damos_quota_goal.py damos_apply_interval.py |
| TEST_PROGS += damos_tried_regions.py damon_nr_regions.py |
| diff --git a/tools/testing/selftests/damon/sysfs.py a/tools/testing/selftests/damon/sysfs.py |
| new file mode 100755 |
| --- /dev/null |
| +++ a/tools/testing/selftests/damon/sysfs.py |
| @@ -0,0 +1,42 @@ |
| +#!/usr/bin/env python3 |
| +# SPDX-License-Identifier: GPL-2.0 |
| + |
| +import json |
| +import os |
| +import subprocess |
| + |
| +import _damon_sysfs |
| + |
| +def dump_damon_status_dict(pid): |
| + file_dir = os.path.dirname(os.path.abspath(__file__)) |
| + dump_script = os.path.join(file_dir, 'drgn_dump_damon_status.py') |
| + rc = subprocess.call(['drgn', dump_script, pid, 'damon_dump_output'], |
| + stderr=subprocess.DEVNULL) |
| + if rc != 0: |
| + return None, 'drgn fail' |
| + try: |
| + with open('damon_dump_output', 'r') as f: |
| + return json.load(f), None |
| + except Exception as e: |
| + return None, 'json.load fail (%s)' % e |
| + |
| +def main(): |
| + kdamonds = _damon_sysfs.Kdamonds( |
| + [_damon_sysfs.Kdamond(contexts=[_damon_sysfs.DamonCtx()])]) |
| + err = kdamonds.start() |
| + if err is not None: |
| + print('kdamond start failed: %s' % err) |
| + exit(1) |
| + |
| + status, err = dump_damon_status_dict(kdamonds.kdamonds[0].pid) |
| + if err is not None: |
| + print(err) |
| + exit(1) |
| + |
| + if len(status['contexts']) != 1: |
| + print('number of contexts: %d' % len(status['contexts'])) |
| + exit(1) |
| + kdamonds.stop() |
| + |
| +if __name__ == '__main__': |
| + main() |
| _ |