This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Refactor the tab completion test utilities and document found bugs
Needs ReviewPublic

Authored by teemperor on Sep 1 2020, 9:13 AM.

Details

Reviewers
JDevlieghere
Summary

Nearly all of our tab completion tests are powered by lldbtest's complete_from_to which is expected to gather the tab completions LLDB provides and then check the result. While debugging a random failure in TestCompletion in b51321ccc894 I noticed how the semantics of complete_from_to are rather forgiving.

Just to recapitulate how LLDB completions work: LLDB's HandleCompletion function computes a list of strings that are all completions for the current command token (not the whole command line). The first string has a magic meaning as it's the common prefix of all provided completions that LLDB for some reason tries to compute for the client.

complete_from_to has some interesting approaches to testing HandleCompletion:

  1. It runs HandleCompletion, looks at the output and then decides based on the output whether the caller wants to check the common prefix (the first magic element) or the rest of the list. This lead to the obscure bug in b51321ccc894. It seems really odd that a test function guesses based on the result what is the most likely thing the test actually wants to test.
  2. The way one checks that a command has no completions is to do complete_from_to("cmd", "cmd"). This check is rather forgiving it seems as it apparently can't fail (at least there are several commands that are expected to fail but are magically passing in our test suit).
  3. It actually just does substr search on the whole command line including the user input when checking results. One test didn't even specify a valid LLDB command but still passed as the function found the completion in the user input...
  4. It contains a bunch of code for regex-based result matching but no one is actually doing that. This just causes that we have a bunch of workaround code to escape regex or turn this feature off.
  5. The error messages on failure are really not useful and look like this: 'process attach -p 1' does not match expected result, got 'process attach -p 1' (that's a real error).

Given that the problem here is just matching a list of strings, I think we can really simplify this whole setup by just using normal asserts.

This patch replaces complete_from_to with three small test functions that just gather the completion strings and then use the normal assert* functions from Python's unittest. The test functions are for an exhaustive check of completions, a subset of completions (for tests where we the possible list of completions can change) and an explicit call to assert no completions.

  • This means that we now get the really helpful error messages from the assert* functions (which even include diffs of what strings/characters are different).
  • I completely removed the regex testing as no one is actually using it at the moment.
  • I removed the whole approach of substr searching and we just use string equality to prevent bogus passes.
  • Removed the requirement to specify the whole command that should be completed. The function also no longer searches the user input for 'expected' completions. This just made most calls to complete_from_to really verbose and lead to bogus passes.
  • Removed my own test functions that I wrote for the expression completion test. Apparently I already run into this issue back then.
  • Added FIXMEs to the checks that were incorrectly passing before now.

Diff Detail

Event Timeline

teemperor requested review of this revision.Sep 1 2020, 9:13 AM
teemperor created this revision.
teemperor planned changes to this revision.Sep 1 2020, 9:21 AM
teemperor added inline comments.
lldb/test/API/commands/expression/completion/TestExprCompletion.py
112

Just realized I didn't re-add that feature yet to the new test function...

This is great, thanks for taking the time to fix all this.

lldb/packages/Python/lldbsuite/test/lldbtest.py
2259–2267

While you're here... can you document the magic values?

2293

Maybe add another assert that len(expected_completions) <= len(returned_completions)

teemperor edited the summary of this revision. (Show Details)Sep 1 2020, 10:10 AM
teemperor updated this revision to Diff 289490.Sep 2 2020, 9:23 AM
  • Make the assert_completions_contains remove an element after it was found (to prevent finding the same element twice).
  • Removed special assert for negative return codes.
teemperor added inline comments.Sep 2 2020, 9:54 AM
lldb/packages/Python/lldbsuite/test/lldbtest.py
2259–2267

Totally forgot I already removed them from the internal logic and I doubt anyone handled them in the SB API. So I just removed that assert as the one below should cover it.

2293

I'm not removing any matches element which should do the same trick but is even stricter (and generates has a nicer error message).

MrHate added a subscriber: MrHate.Sep 18 2020, 1:05 AM