[PATCH v3] dts: add test case docstring checks to format script
Dean Marx
dmarx at iol.unh.edu
Thu Nov 6 19:13:55 CET 2025
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>
---
devtools/dts-check-docstrings.py | 54 ++++++++++++++++++++++++++++++++
devtools/dts-check-format.sh | 8 +++++
2 files changed, 62 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..f2cd5a56a1 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,13 @@ if $lint; then
echo "ruff not found, unable to run linter"
errors=$((errors + 1))
fi
+ if $docstringcheck; then
+ docstring_script_path=$(dirname "$0")
+ docstring_script_path=$(cd "$docstring_script_path" && pwd)
+ docstring_script="$docstring_script_path/dts-check-docstrings.py"
+ $docstring_script
+ errors=$((errors + $?))
+ fi
fi
if $typecheck; then
--
2.51.0
More information about the dev
mailing list