2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00
ovs/tests/checkpatch.at
Aaron Conole eeb7d7d995 checkpatch: Separate out the built-in spelling words.
Checkpatch contains a large list of spelling words, currently 326.  The
in-built list is quite cumbersome, and includes duplicate entries
('netdev' and 'revalidation').  Managing this list will continue to grow
difficult over time, and really shouldn't be so difficult.  To make the
maintenance of OVS specific spelling words easier, create a new file
that will contain the spelling words and move the list into that file
(sorted).  This patch adds 'FreeBSD' and 'gcloud' to the list as it
was tested against
80d723736b64 ("cirrus: Update to FreeBSD 14.3 and 13.5.").  It also
adds "apis", "enablement", "ifdef", and "tnl" after the patch proposed
by Eelco at the referenced link.

Link: d6fecfc949.1750328980.git.echaudro@redhat.com/
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Acked-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Aaron Conole <aconole@redhat.com>
2025-07-16 08:39:25 -04:00

767 lines
17 KiB
Plaintext
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

AT_BANNER([checkpatch])
OVS_START_SHELL_HELPERS
# try_checkpatch PATCH [ERRORS] [checkpatch-args]
#
# Runs checkpatch, if installed, on the given PATCH, expecting the
# specified set of ERRORS (and warnings).
try_checkpatch() {
# Take the patch to test from $1. Remove an initial four-space indent
# from it and, if it is just headers with no body, add a null body.
# If it does not have a 'Subject', add a valid one.
echo "$1" | sed 's/^ //' > test.patch
if grep 'Subject\:' test.patch >/dev/null 2>&1; then :
else
sed -i'' -e '1i\
Subject: Patch this is.
' test.patch
fi
if grep '---' expout >/dev/null 2>&1; then :
else
printf '\n---\n' >> test.patch
fi
# Take expected output from $2.
if test -n "$2"; then
echo "$2" | sed 's/^ //' > expout
else
: > expout
fi
if test -s expout; then
AT_CHECK([OVS_SRC_DIR=$top_srcdir $PYTHON3 \
$top_srcdir/utilities/checkpatch.py $3 -q test.patch],
[1], [stdout])
AT_CHECK([sed '/^Lines checked:/,$d' stdout], [0], [expout])
else
AT_CHECK([OVS_SRC_DIR=$top_srcdir $PYTHON3 \
$top_srcdir/utilities/checkpatch.py $3 -q test.patch])
fi
}
# try_checkpatch_c_file SOURCE [ERRORS] [CHECKPATCH-ARGS] [FILTER]
#
# Runs checkpatch against test SOURCE expecting the set of specified
# ERRORS (and warnings). Optionally, sets [CHECKPATCH-ARGS]. The
# optional FILTER can be used to adjust the expected output before
# processing.
try_checkpatch_c_file() {
echo "$1" | sed 's/^ //' > test.c
# Take expected output from $2.
if test -n "$2"; then
echo "$2" | sed 's/^ //' > expout
else
: > expout
fi
if test -s expout; then
AT_CHECK([OVS_SRC_DIR=$top_srcdir $PYTHON3 \
$top_srcdir/utilities/checkpatch.py $3 -q -f test.c],
[1], [stdout])
AT_CHECK([sed "$4
/^Lines checked:/d
/^$/d" stdout], [0], [expout])
else
AT_CHECK([OVS_SRC_DIR=$top_srcdir $PYTHON3 \
$top_srcdir/utilities/checkpatch.py $3 -q -f test.c])
fi
}
OVS_END_SHELL_HELPERS
AT_SETUP([checkpatch - sign-offs])
# Sign-off for single author who is also the committer.
try_checkpatch \
"Author: A
Commit: A
Signed-off-by: A"
try_checkpatch \
"Author: A
Commit: A" \
"ERROR: Author A needs to sign off."
# Single author but somehow the mailing list is the author.
try_checkpatch \
"Author: Foo Bar via dev <ovs-dev@openvswitch.org>
Commit: A
Signed-off-by: A" \
"ERROR: Author should not be mailing list."
# Sign-off for single author and different committer.
try_checkpatch \
"Author: A
Commit: B
Signed-off-by: A
Signed-off-by: B"
try_checkpatch \
"Author: A
Commit: B" \
"ERROR: Author A needs to sign off.
ERROR: Committer B needs to sign off."
# Sign-off for multiple authors with one author also the committer.
try_checkpatch \
"Author: A
Commit: A
Signed-off-by: A
Co-authored-by: B
Signed-off-by: B"
try_checkpatch \
"Author: A
Commit: A
Co-authored-by: B
Signed-off-by: B" \
"ERROR: Author A needs to sign off."
try_checkpatch \
"Author: A
Commit: A
Signed-off-by: A
Co-authored-by: B" \
"ERROR: Co-author B needs to sign off."
try_checkpatch \
"Author: A
Commit: A
Co-authored-by: B" \
"ERROR: Author A needs to sign off.
ERROR: Co-author B needs to sign off."
# Sign-off for multiple authors and separate committer.
try_checkpatch \
"Author: A
Commit: C
Signed-off-by: A
Co-authored-by: B
Signed-off-by: B
Signed-off-by: C"
try_checkpatch \
"Author: A
Commit: C
Signed-off-by: A
Co-authored-by: B
Signed-off-by: B" \
"ERROR: Committer C needs to sign off."
# Extra sign-offs:
#
# - If we know the committer, one extra sign-off raises a warning.
#
# - If we do not know the committer, two extra sign-offs raise a warning.
try_checkpatch \
"Author: A
Commit: C
Signed-off-by: A
Co-authored-by: B
Signed-off-by: B
Signed-off-by: C
Signed-off-by: D" \
"WARNING: Unexpected sign-offs from developers who are not authors or co-authors or committers: D"
try_checkpatch \
"Author: A
Signed-off-by: A
Co-authored-by: B
Signed-off-by: B
Signed-off-by: C"
try_checkpatch \
"Author: A
Signed-off-by: A
Co-authored-by: B
Signed-off-by: B
Signed-off-by: C
Signed-off-by: D" \
"WARNING: Unexpected sign-offs from developers who are not authors or co-authors or committers: C, D"
# Missing committer is OK, missing author is an error.
try_checkpatch \
"Author: A
Signed-off-by: A"
try_checkpatch \
"Commit: A
Signed-off-by: A" \
"ERROR: Patch lacks author."
AT_CLEANUP
m4_define([COMMON_PATCH_HEADER], [dnl
Author: A
Signed-off-by: A
---
diff --git a/$([[ ! -z "$1" ]] && echo "$1" || echo "A.c") b/$([[ ! -z "$1" ]] && echo "$1" || echo "A.c")
index 0000000..1111111 100644
--- a/$([[ ! -z "$1" ]] && echo "$1" || echo "A.c")
+++ b/$([[ ! -z "$1" ]] && echo "$1" || echo "A.c")
@@ -1,1 +1,1 @@])
AT_SETUP([checkpatch - parenthesized constructs])
for ctr in 'if' 'while' 'switch' 'HMAP_FOR_EACH' 'BITMAP_FOR_EACH_1'; do
try_checkpatch \
"COMMON_PATCH_HEADER
+ $ctr (first_run) {
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ $ctr ( first_run) {
" \
"ERROR: Improper whitespace around control block
#8 FILE: A.c:1:
$ctr ( first_run) {
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ $ctr (first_run ) {
" \
"ERROR: Inappropriate bracing around statement
#8 FILE: A.c:1:
$ctr (first_run ) {
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ $ctr (first_run)
" \
"ERROR: Inappropriate bracing around statement
#8 FILE: A.c:1:
$ctr (first_run)
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ $ctr(first_run)
" \
"ERROR: Improper whitespace around control block
#8 FILE: A.c:1:
$ctr(first_run)
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ $ctr (first_run) { /* foo */
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ $ctr (first_run) { \\
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ $ctr (a) { \\
"
done
AT_CLEANUP
AT_SETUP([checkpatch - catastrophic backtracking])
dnl Special case this rather than using the above construct because sometimes a
dnl warning needs to be generated for line lengths (f.e. when the 'while'
dnl keyword is used).
try_checkpatch \
"COMMON_PATCH_HEADER
+ if (!b_ctx_in->chassis_rec || !b_ctx_in->br_int || !b_ctx_in->ovs_idl_txn)
" \
"ERROR: Inappropriate bracing around statement
#8 FILE: A.c:1:
if (!b_ctx_in->chassis_rec || !b_ctx_in->br_int || !b_ctx_in->ovs_idl_txn)
"
AT_CLEANUP
AT_SETUP([checkpatch - parenthesized constructs - for])
try_checkpatch \
"COMMON_PATCH_HEADER
+ for (init; condition; increment) {
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ for ( init; condition; increment) {
" \
"ERROR: Improper whitespace around control block
#8 FILE: A.c:1:
for ( init; condition; increment) {
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ for (init; condition; increment ) {
" \
"ERROR: Inappropriate bracing around statement
#8 FILE: A.c:1:
for (init; condition; increment ) {
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ for (init; condition; increment)
" \
"ERROR: Inappropriate bracing around statement
#8 FILE: A.c:1:
for (init; condition; increment)
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ for(init; condition; increment)
" \
"ERROR: Improper whitespace around control block
#8 FILE: A.c:1:
for(init; condition; increment)
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ for (init; condition; increment) { /* foo */
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ for (init; condition; increment) { \\
"
try_checkpatch \
"COMMON_PATCH_HEADER
+#define SOME_FOR_EACH(a, b, c) /* Foo. */
"
AT_CLEANUP
AT_SETUP([checkpatch - comments])
try_checkpatch \
"COMMON_PATCH_HEADER
+ a = 1; /* C style comment. */
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ /* http://URL/inside/the/comment.html */
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ a = 1; // C99 style comment.
" \
"ERROR: C99 style comment
#8 FILE: A.c:1:
a = 1; // C99 style comment.
"
AT_CLEANUP
AT_SETUP([checkpatch - whitespace around operator])
try_checkpatch \
"COMMON_PATCH_HEADER
+ if (--mcs->n_refs == 0) {
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ if (--mcs->n_refs==0) {
" \
"WARNING: Line lacks whitespace around operator
WARNING: Line lacks whitespace around operator
#8 FILE: A.c:1:
if (--mcs->n_refs==0) {
"
try_checkpatch \
"COMMON_PATCH_HEADER
+char *string;
+char **list;
+char ***ptr_list;
"
try_checkpatch \
"COMMON_PATCH_HEADER
+char** list;
" \
"WARNING: Line lacks whitespace around operator
#8 FILE: A.c:1:
char** list;
"
try_checkpatch \
"COMMON_PATCH_HEADER
+char*** list;
" \
"WARNING: Line lacks whitespace around operator
#8 FILE: A.c:1:
char*** list;
"
AT_CLEANUP
AT_SETUP([checkpatch - check misuse APIs])
try_checkpatch \
"COMMON_PATCH_HEADER([a.c])
+ ovsrcu_barrier();
" \
"WARNING: Are you sure you need to use ovsrcu_barrier(), "\
"in most cases ovsrcu_synchronize() will be fine?
#8 FILE: a.c:1:
ovsrcu_barrier();
"
try_checkpatch \
"COMMON_PATCH_HEADER([lib/ovs-rcu.c])
+ ovsrcu_barrier();
"
AT_CLEANUP
AT_SETUP([checkpatch - check egrep / fgrep])
try_checkpatch \
"COMMON_PATCH_HEADER([tests/something.at])
+C_H_E_C_K([[ovs-vsctl show | grep -E 'my-port.*[[0-9]]$' | grep -F 'port']])
"
try_checkpatch \
"COMMON_PATCH_HEADER([tests/something.at])
+C_H_E_C_K([[ovs-vsctl show | egrep 'my-port.*[[0-9]]$']])
" \
"ERROR: grep -E/-F should be used instead of egrep/fgrep
#8 FILE: tests/something.at:1:
C_H_E_C_K([[ovs-vsctl show | egrep 'my-port.*[[0-9]]$']])
"
try_checkpatch \
"COMMON_PATCH_HEADER([tests/something.at])
+C_H_E_C_K([[ovs-vsctl show | fgrep 'my-port.*[[0-9]]$']])
" \
"ERROR: grep -E/-F should be used instead of egrep/fgrep
#8 FILE: tests/something.at:1:
C_H_E_C_K([[ovs-vsctl show | fgrep 'my-port.*[[0-9]]$']])
"
AT_CLEANUP
AT_SETUP([checkpatch - whitespace around cast])
try_checkpatch \
"COMMON_PATCH_HEADER
+ (int) a;
"
try_checkpatch \
"COMMON_PATCH_HEADER
+ (int)a;
" \
"ERROR: Inappropriate spacing around cast
#8 FILE: A.c:1:
(int)a;
"
AT_CLEANUP
AT_SETUP([checkpatch - malformed tags])
try_checkpatch \
" Author: A
Acked by: foo...
Signed-off-by: A" \
"ERROR: Acked-by tag is malformed.
1: Acked by: foo...
"
try_checkpatch \
" Author: A
Reported at: foo...
Signed-off-by: A" \
"ERROR: Reported-at tag is malformed.
1: Reported at: foo...
"
try_checkpatch \
" Author: A
Reported by: foo...
Signed-off-by: A" \
"ERROR: Reported-by tag is malformed.
1: Reported by: foo...
"
try_checkpatch \
" Author: A
Requested by: foo...
Signed-off-by: A" \
"ERROR: Requested-by tag is malformed.
1: Requested by: foo...
"
try_checkpatch \
" Author: A
Reviewed by: foo...
Signed-off-by: A" \
"ERROR: Reviewed-by tag is malformed.
1: Reviewed by: foo...
"
try_checkpatch \
" Author: A
Submitted at: foo...
Signed-off-by: A" \
"ERROR: Submitted-at tag is malformed.
1: Submitted at: foo...
"
try_checkpatch \
" Author: A
Suggested by: foo...
Signed-off-by: A" \
"ERROR: Suggested-by tag is malformed.
1: Suggested by: foo...
"
AT_CLEANUP
AT_SETUP([checkpatch - Unicode code])
try_checkpatch \
"COMMON_PATCH_HEADER
+ if (snowman == ☃️) { /* Emoji
+ void НelloWorld() { /* Homoglyph
+ ة /* ;C++ /* BiDi
" \
"ERROR: Inappropriate non-ascii characters detected.
#8 FILE: A.c:1:
if (snowman == ☃️) { /* Emoji
ERROR: Inappropriate non-ascii characters detected.
#9 FILE: A.c:2:
void НelloWorld() { /* Homoglyph
ERROR: Inappropriate non-ascii characters detected.
#10 FILE: A.c:3:
ة /* ;C++ /* BiDi
"
AT_CLEANUP
m4_define([FIXES_TAG_ERROR], [dnl
ERROR: \"Fixes\" tag is malformed.
Use the following format:
git log -1 --pretty=format:\"Fixes: %h (\\\"%s\\\")\" --abbrev=12 COMMIT_REF
])
AT_SETUP([checkpatch - Fixes tag])
try_checkpatch \
"Author: A
Commit: A
Fixes: 123456789abc (\"commit name\")
Signed-off-by: A"
try_checkpatch \
"Author: A
Commit: A
fixes: 123456789abc (\"commit name\")
Signed-off-by: A" \
"FIXES_TAG_ERROR
1: fixes: 123456789abc (\"commit name\")
"
try_checkpatch \
"Author: A
Commit: A
Fixes: 12345678 (\"commit name\")
Signed-off-by: A" \
"FIXES_TAG_ERROR
1: Fixes: 12345678 (\"commit name\")
"
try_checkpatch \
"Author: A
Commit: A
Fixes: 1234567890abcdef1234567890abcdef12345678 (\"commit name\")
Signed-off-by: A" \
"FIXES_TAG_ERROR
1: Fixes: 1234567890abcdef1234567890abcdef12345678 (\"commit name\")
"
try_checkpatch \
"Author: A
Commit: A
Fixes: 123456789abc \"commit name\"
Signed-off-by: A" \
"FIXES_TAG_ERROR
1: Fixes: 123456789abc \"commit name\"
"
try_checkpatch \
"Author: A
Commit: A
Fixes: 123456789abc (\"some very long commit name that doesn\'t fit into
a single line, but should not be wrapped.\")
Signed-off-by: A" \
"FIXES_TAG_ERROR
1: Fixes: 123456789abc (\"some very long commit name that doesn\'t fit into
"
AT_CLEANUP
AT_SETUP([checkpatch - subject])
try_checkpatch \
"Author: A
Commit: A
Subject: netdev: invalid case and dot ending
Signed-off-by: A" \
"WARNING: The subject summary should start with a capital.
WARNING: The subject summary should end with a dot.
Subject: netdev: invalid case and dot ending"
try_checkpatch \
"Author: A
Commit: A
Subject: netdev: This is a way to long commit summary and therefor it should report a WARNING!
Signed-off-by: A" \
"WARNING: The subject, '<area>: <summary>', is over 70 characters, i.e., 85.
Subject: netdev: This is a way to long commit summary and therefor it should report a WARNING!"
AT_CLEANUP
AT_SETUP([checkpatch - ignore committer as signoff])
try_checkpatch \
"Author: A
Commit: B
Subject: netdev: Subject.
Signed-off-by: A" \
"ERROR: Committer B needs to sign off."
try_checkpatch \
"Author: A
Commit: B
Subject: netdev: Subject.
Signed-off-by: A" \
"" \
"--skip-committer-signoff"
AT_CLEANUP
AT_SETUP([checkpatch - AUTHORS.rst existence])
try_checkpatch \
"Author: A <a@a.com>
Commit: A <a@a.com>
Subject: netdev: Subject.
Signed-off-by: A <a@a.com>" \
""
try_checkpatch \
"Author: A <a@a.com>
Commit: A <a@a.com>
Subject: netdev: Subject.
Signed-off-by: A <a@a.com>" \
"WARNING: Author 'A <a@a.com>' is not in the AUTHORS.rst file!" \
"-a"
AT_CLEANUP
AT_SETUP([checkpatch - file contents checks - bare return])
try_checkpatch_c_file \
"#include <foo.h>
#include <bar.h>
void foo() {
return;
}" \
"WARNING: Empty return followed by brace, consider omitting
test.c:6:
}"
AT_CLEANUP
AT_SETUP([checkpatch - file contents checks - parenthesized constructs])
for ctr in 'if' 'while' 'switch' 'HMAP_FOR_EACH' 'BITMAP_FOR_EACH_1'; do
try_checkpatch_c_file \
"#include <foo.h>
#include <bar.h>
void foo() {
$ctr (check_node) {
something(check_node);
}
}
"
try_checkpatch_c_file \
"#include <foo.h>
#include <bar.h>
void foo() {
$ctr ( first_run) {
something(check_node);
}
}" \
"ERROR: Improper whitespace around control block
test.c:5:
$ctr ( first_run) {"
done
AT_CLEANUP
AT_SETUP([checkpatch - spelling checks])
AT_SKIP_IF([! $PYTHON3 -c 'import enchant' >/dev/null 2>&1])
dnl First check with some default words
try_checkpatch_c_file \
"#include <foo.h>
#include <bar.h>
/* naintenance mode */
void foo() {
$ctr ( first_run ) {
something(check_node);
}
}" \
"WARNING: Possible misspelled word: \"naintenance\"
test.c:4:
/* naintenance mode */" \
"-S" \
"/^Did you mean:/d"
try_checkpatch_c_file \
"#include <foo.h>
#include <bar.h>
/* hugepage mode */
void foo() {
$ctr ( first_run ) {
something(check_node);
}
}" \
"" \
"-S"
AT_CLEANUP