[PATCH v4 1/2] dts: add test case docstring checks to format script
Patrick Robb
probb at iol.unh.edu
Fri Jan 30 18:11:16 CET 2026
Thanks Dean. Series applied to next-dts.
On Thu, Jan 22, 2026 at 12:47 PM Dean Marx <dmarx at iol.unh.edu> wrote:
>
> Add a python script that checks all test cases
> to ensure each docstring contains a steps and
> verify section in accordance with coding guidelines.
> Add a section within the check-format script which
> calls the docstring script after linting with ruff.
>
> Bugzilla ID: 1623
>
> Signed-off-by: Dean Marx <dmarx at iol.unh.edu>
> Reviewed-by: Patrick Robb <probb at iol.unh.edu>
> ---
> devtools/dts-check-docstrings.py | 54 ++++++++++++++++++++++++++++++++
> devtools/dts-check-format.sh | 5 +++
> 2 files changed, 59 insertions(+)
> create mode 100755 devtools/dts-check-docstrings.py
>
> diff --git a/devtools/dts-check-docstrings.py b/devtools/dts-check-docstrings.py
> new file mode 100755
> index 0000000000..3b0d2a42a1
> --- /dev/null
> +++ b/devtools/dts-check-docstrings.py
> @@ -0,0 +1,54 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2025 University of New Hampshire
> +
> +import sys
> +from ast import FunctionDef, Name, walk, get_docstring, parse
> +from pathlib import Path
> +
> +BASE_DIR = Path(__file__).resolve().parent.parent # dpdk/
> +TESTS_DIR = BASE_DIR / "dts" / "tests" # dts/tests/
> +DECORATOR_NAMES = {"func_test", "perf_test"}
> +
> +
> +def has_test_decorator(node: FunctionDef) -> bool:
> + """Return True if function has @func_test or @perf_test decorator."""
> + for decorator in node.decorator_list:
> + if isinstance(decorator, Name) and decorator.id in DECORATOR_NAMES:
> + return True
> + return False
> +
> +
> +def check_file(path: Path) -> bool:
> + """Return True if file has steps and verify sections in each test case docstring."""
> + source = path.read_text(encoding="utf-8")
> + tree = parse(source, filename=str(path))
> + ok = True
> +
> + for node in walk(tree):
> + if isinstance(node, FunctionDef):
> + if has_test_decorator(node):
> + doc = get_docstring(node)
> + if not doc:
> + print(f"{path}:{node.lineno} missing docstring for test case")
> + ok = False
> + else:
> + if "Steps:" not in doc:
> + print(f"{path}:{node.lineno} missing 'Steps:' section")
> + ok = False
> + if "Verify:" not in doc:
> + print(f"{path}:{node.lineno} missing 'Verify:' section")
> + ok = False
> + return ok
> +
> +
> +def main():
> + all_ok = True
> + for path in TESTS_DIR.rglob("*.py"):
> + if not check_file(path):
> + all_ok = False
> + sys.exit(0 if all_ok else 1)
> +
> +
> +if __name__ == "__main__":
> + main()
> diff --git a/devtools/dts-check-format.sh b/devtools/dts-check-format.sh
> index 907eed1293..23c0a5f1da 100755
> --- a/devtools/dts-check-format.sh
> +++ b/devtools/dts-check-format.sh
> @@ -13,6 +13,7 @@ usage() {
> format=true
> lint=true
> typecheck=true
> +docstringcheck=true
>
> # Comments after args serve as documentation; must be present
> while getopts "hflt" arg; do
> @@ -97,6 +98,10 @@ if $lint; then
> echo "ruff not found, unable to run linter"
> errors=$((errors + 1))
> fi
> + if $docstringcheck; then
> + python3 ../devtools/dts-check-docstrings.py
> + errors=$((errors + $?))
> + fi
> fi
>
> if $typecheck; then
> --
> 2.52.0
>
More information about the dev
mailing list