Skip to content

Commit 4df656c

Browse files
committed
tests: kdoc: improve comparison and output
Currently, the kdoc test fails when the number of lines of outout from ./scripts/kernel-doc increases. This is a decent heuristic but can fail in some cases. For example, if a patch adds one warning but removes another, the total line count may not change. This could result in false negatives where some patches do not fail the test despite adding new warnings. Upon detecting a difference in warning count, the test uses diff to compare the old and new warnings. This output is not very useful to humans. The diff comparison includes the line numbers which are impacted by code movement, making relevant warnings difficult to spot when reviewing test output. An ideal kdoc test should determine the actual set of new warnings. To achieve this, use the following algorithm: 1) Capture the kernel-doc output for the old commit 2) Capture the kernel-doc output for the new commit 3) Carefully join and sort output so that its stable w.r.t line number changes 4) Strip line numbers from the warning content for both old and new output 5) Diff the stripped output, using --*-group-format to just print line number ranges. 6) Use the difference line ranges to print from the unstripped output, generating a set of new and removed warnings. By ensuring that the sorted input is stable even if line numbers change, this correctly locates all of the new warnings, and additionally any removed warnings, avoiding a false test pass. In addition, the output is far more useful for humans as the output is 1) just the new warnings, and doesn't contain diff syntax and 2) doesn't contain warnings whose only change is the line number. This is a bit more complicated, especially since it requires reading through the input and sorting multiple times. However, the end result is significantly more useful. Signed-off-by: Jacob Keller <[email protected]>
1 parent 1668e7a commit 4df656c

File tree

1 file changed

+69
-16
lines changed

1 file changed

+69
-16
lines changed

tests/patch/kdoc/kdoc.sh

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,41 @@
44
# Copyright (C) 2019 Netronome Systems, Inc.
55
# Copyright (c) 2020 Facebook
66

7+
# Cleanup warnings by merging lines which end with ':' to their referenced
8+
# line content, and sorting the output carefully to ensure that the entries
9+
# are stable w.r.t code being re-ordered.
10+
#
11+
# In particular, we sort first by the warning description and then by the
12+
# filename path without its line number element.
13+
#
14+
# This assumes all lines are "Warning:" or "Error:" and that file names do not
15+
# have whitespace.
16+
function merge_and_sort() {
17+
awk '{ if ($0 ~ /:$/) { ORS="" } else { ORS="\n" }; print }' | \
18+
sort -s -k 3 | sort -s -t ':' -k 2,2
19+
}
20+
21+
# Strip out line number information from warnings and errors
22+
function strip_line_numbers() {
23+
sed -e 's@^\(\([Ww]arning\|[Ee]rror\):\s*[/a-zA-Z0-9_.-]*.[ch]\):[0-9]*@\1@' "${@}"
24+
}
25+
26+
# Diff output, printing a sed range expression for any removed lines.
27+
function old_lines_to_range() {
28+
diff --line-format="" --old-group-format="%df,%dlp;" "${@}"
29+
}
30+
31+
# Diff output, printing a sed range expression for any newly added lines.
32+
function new_lines_to_range() {
33+
diff --line-format="" --new-group-format="%dF,%dLp;" "${@}"
34+
}
35+
736
tmpfile_o=$(mktemp)
837
tmpfile_n=$(mktemp)
38+
tmpfile_so=$(mktemp)
39+
tmpfile_sn=$(mktemp)
40+
tmpfile_rm=$(mktemp)
41+
tmpfile_new=$(mktemp)
942
rc=0
1043

1144
files_mod=$(git show --diff-filter=M --pretty="" --name-only "HEAD")
@@ -15,38 +48,58 @@ HEAD=$(git rev-parse HEAD)
1548

1649
echo "Checking the tree before the patch"
1750
git checkout -q HEAD~
18-
./scripts/kernel-doc -Wall -none $files_mod 2> >(tee $tmpfile_o >&2)
51+
52+
echo "Before patch:" >&2
53+
./scripts/kernel-doc -Wall -none $files_mod 2>&1 | merge_and_sort | tee $tmpfile_o >&2
54+
55+
strip_line_numbers $tmpfile_o > $tmpfile_so
1956

2057
incumbent=$(grep -v 'Error: Cannot open file ' $tmpfile_o | wc -l)
2158

2259
echo "Checking the tree with the patch"
2360

2461
git checkout -q $HEAD
25-
./scripts/kernel-doc -Wall -none $files_all 2> >(tee $tmpfile_n >&2)
62+
63+
echo "After patch:" >&2
64+
./scripts/kernel-doc -Wall -none $files_all 2>&1 | merge_and_sort | tee $tmpfile_n >&2
65+
66+
strip_line_numbers $tmpfile_n > $tmpfile_sn
2667

2768
current=$(grep -v 'Error: Cannot open file ' $tmpfile_n | wc -l)
2869

29-
echo "Errors and warnings before: $incumbent this patch: $current" >&$DESC_FD
70+
# Find removed warnings
71+
removed_range=$(old_lines_to_range ${tmpfile_so} ${tmpfile_sn})
72+
sed -n -e "${removed_range}" ${tmpfile_o} > ${tmpfile_rm}
73+
74+
removed=$(grep -v 'Error: Cannot open file ' $tmpfile_rm | wc -l)
75+
76+
# Find new warnings
77+
new_range=$(new_lines_to_range ${tmpfile_so} ${tmpfile_sn})
78+
sed -n -e "${new_range}" ${tmpfile_n} > ${tmpfile_new}
3079

31-
if [ $current -gt $incumbent ]; then
32-
echo "New warnings added" 1>&2
33-
diff $tmpfile_o $tmpfile_n 1>&2
80+
new_warnings=$(grep -v 'Error: Cannot open file ' $tmpfile_new | wc -l)
3481

35-
echo "Per-file breakdown" 1>&2
36-
tmpfile_fo=$(mktemp)
37-
tmpfile_fn=$(mktemp)
82+
echo "Errors and warnings before: $incumbent This patch: $current" >&$DESC_FD
83+
echo "New: $new_warnings Removed: $removed" >&$DESC_FD
84+
85+
if [ $removed -gt 0 ]; then
86+
echo "Warnings removed:" 1>&2
87+
sort -V $tmpfile_rm 1>&2
88+
89+
echo "Per-file breakdown:" 1>&2
90+
grep -i "\(warn\|error\)" $tmpfile_rm | sed -n 's@^\([Ww]arning\|[Ee]rror\):\s*\([/a-zA-Z0-9_.-]*.[ch]\):.*@\2@p' | sort | uniq -c 1>&2
91+
fi
3892

39-
grep -i "\(warn\|error\)" $tmpfile_o | sed -n 's@\(^[/a-zA-Z0-9_.-]*.[ch]\):.*@\1@p' | sort | uniq -c \
40-
> $tmpfile_fo
41-
grep -i "\(warn\|error\)" $tmpfile_n | sed -n 's@\(^[/a-zA-Z0-9_.-]*.[ch]\):.*@\1@p' | sort | uniq -c \
42-
> $tmpfile_fn
93+
if [ $new_warnings -gt 0 ]; then
94+
echo "New warnings added:" 1>&2
95+
sort -V $tmpfile_new 1>&2
4396

44-
diff $tmpfile_fo $tmpfile_fn 1>&2
45-
rm $tmpfile_fo $tmpfile_fn
97+
echo "Per-file breakdown:" 1>&2
98+
grep -i "\(warn\|error\)" $tmpfile_new | sed -n 's@^\([Ww]arning\|[Ee]rror\):\s*\([/a-zA-Z0-9_.-]*.[ch]\):.*@\2@p' | sort | uniq -c 1>&2
4699

47100
rc=1
48101
fi
49102

50-
rm $tmpfile_o $tmpfile_n
103+
rm $tmpfile_o $tmpfile_n $tmpfile_so $tmpfile_sn
51104

52105
exit $rc

0 commit comments

Comments
 (0)