- 
                Notifications
    You must be signed in to change notification settings 
- Fork 12
tests: kdoc: switch to python and improve algorithm #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tests: kdoc: switch to python and improve algorithm #57
Conversation
The existing kdoc test is written in shell, based on a simple heuristic of checking whether the number of lines of output from scripts/kernel-doc increases. This test can pass in some cases even when new warnings are introduced, such as if a single patch adds some new warnings while removing others. In addition, the provided log output is not very useful to humans. It uses a traditional diff to compare the prior and current warnings. Because the warnings include line number data, this results in an unreadable mess. Implementing a proper comparison in the shell script is possible, but the resulting logic and code is difficult to maintain. Ultimately, what we want to do is a sort of set intersection on the warnings while ignoring line numbers. Implementing this in python is much more practical. As a first step, convert the kdoc test into a python module. Commands are executed via subprocess. The improved comparison algorithm will be implemented in a following change. Since we will be implementing a new comparison algorithm, do not bother porting the "diff" implementation forward. This results in a temporary regression as we no longer compute the difference or file summary for the user. This will be resolved with the following change implementing the improved algorithm. This version has a couple of minor changes worth nothing: 1) The log output is now in stdout instead of stderr, since the python-based tests do not support logging output to the stderr file. 2) We no longer print out "Checking the tree..." lines. 3) The description line is included within the stdout log text as well as the desc file. Signed-off-by: Jacob Keller <[email protected]>
The current algorithm for the kdoc test is a simple line number comparison of the output from ./scripts/kernel-doc. This is not guaranteed to be accurate, as a patch could fix some warnings while introducing others, resulting in the total number of lines not changing. In addition, it is difficult to quickly determine which warnings are new. Historically, a simple "diff" was used to compare the before and after results. This was difficult to parse because line numbers change due to code being added or moved. To fix this, use a set difference algorithm which compares based on data from the warning lines without including the line number. To do this, introduce a KdocWarning dataclass, which represents a warning based on its kind, file, line, and content. Extract these from the lines via a regular expression that looks for the expected pattern of output from ./scripts/kernel-doc. Using a @DataClass allows specifying which fields to compare against. In particular, the line number is not counted. Additionally, the original message as output from ./scripts/kernel-doc is preserved as its own (non-compared) field. Some warnings are spread over two lines, indicated by the first line ending in a semicolon. Handle this when iterating over the output of kernel-doc and converting to the new warning objects. Any output line which doesn't match the regular expression is converted so that its entire message becomes the contents. This ensures that such lines still get counted and still get compared in some form, rather than silently ignored. After obtaining the converted output from ./scripts/kernel-doc, convert the current_warnings and incumbent_warnings lists into sets. Calculate the set of new and removed warnings by iterating the original lists. For new_warnings, find the sequence of warnings which are in the current_warnings but not in the incumbent set. Do the same to calculate the set of removed warnings. This implementation is fast, as it can use the hash-based comparisons for efficient set lookup. Using the original list also preserves the order of the warnings as output by ./scripts/kernel-doc. Calculating both the new and removed counts provides useful data for users of the NIPA tests. It is much easier to see at a glance what warnings were added. Signed-off-by: Jacob Keller <[email protected]>
3c77b76    to
    1209a47      
    Compare
  
    | Tony pointed out a bug from his testing: the description strings were missing the f for format strings, so not being interpolated. I just fixed that. | 
| Thanks! Will deploy in a an hour or two. | 
| I fixed it a little bit already but it looks still broken eg: https://patchwork.kernel.org/project/netdevbpf/patch/[email protected]/ | 
| I'll take a look today. It appears like either the output changed or some output I hadn't seen, so we need to extend the parser to handle the parse failed bits and some other data. Will see what I can figure out this afternoon. | 
| It looks like the logic you added to log bad parses was placed incorrectly, so almost all lines are warned about (except those which merge two lines together). I've got a fix for that. It also looks like kernel-doc is producing some warnings with just a line number, I haven't figure out why that happens yet. I'll push this PR to fix the logging and then continue investigating whats gone wrong with kernel-doc. | 
I had a look at the kdoc test output for some patches recently, and found it
to be essentially unusable as a tool for quickly resolving new warnings. The
provided output is a diff (traditional, not even a unified context) format
which includes also warnings whose line number changed. This results in many
pre-existing warnings being reported. Spotting the actually new warnings is
quite difficult.
In addition, that original test can produce false positives. If a patch
introduces new warnings while removing others, the total number of
kernel-doc warnings might stay the same, thus allowing the test to pass
despite having new warnings.
A much better algorithm is to compare the warnings before and after without
the line numbers. I originally implemented such an algorithm in the shell
script via a complex set of awk, sed, and diff with the custom
'--*group-format' options. This worked, but is rather complex and somewhat
difficult to maintain.
Instead, this version re-implements the kdoc test entirely in python using
subprocess to execute the ./scripts/kernel-doc program. Line output is
converted into a custom KdocWarning dataclass using a regular expression to
extract the file and line paths. Comparisons are implemented only on the
file and content sections, ignoring line numbers.
Once captured, the results are converted into sets which we can perform set
difference on to compute the set of added and removed warnings. A quick
comparison on my 14 patch series shows that the new python implementation is
actually faster than the baseline original implementation:
Baseline time:
real 0m52.290s
user 0m45.392s
sys 0m44.627s
Shell implementation:
real 0m52.769s
user 0m45.504s
sys 0m45.365s
Python implementation:
real 0m49.179s
user 0m43.721s
sys 0m42.877s
The python version has several advantages over the shell version:
Here's an example of the output difference, with the current implementation shown first:
Now the new results:
This output is significantly more readable and useful for humans. It is also
more robust as it closes a possible loophole in patches adding and removing
warnings in the same change.