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 <dm...@iol.unh.edu> --- devtools/check-docstrings.py | 52 ++++++++++++++++++++++++++++++++++++ devtools/dts-check-format.sh | 7 +++++ 2 files changed, 59 insertions(+) create mode 100755 devtools/check-docstrings.py diff --git a/devtools/check-docstrings.py b/devtools/check-docstrings.py new file mode 100755 index 0000000000..0baee6e383 --- /dev/null +++ b/devtools/check-docstrings.py @@ -0,0 +1,52 @@ +# 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 # dpdk/ +TESTS_DIR = BASE_DIR.parent / "dts" / "tests" # dts/tests/ + + +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 {"func_test", "perf_test"}: + 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..5f93a11a16 100755 --- a/devtools/dts-check-format.sh +++ b/devtools/dts-check-format.sh @@ -86,7 +86,14 @@ if $lint; then ruff check --fix errors=$((errors + $?)) + docstring_script_path=$(dirname "$0") + docstring_script_path=$(cd "$docstring_script_path" && pwd) + docstring_script="$docstring_script_path/check-docstrings.py" + python "$docstring_script" + errors=$((errors + $?)) + git update-index --refresh + retval=$? if [ $retval -ne 0 ]; then echo 'The "needs update" files have been fixed by the linter.' -- 2.50.1