-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Extend stacktrace for failed tests not directly under testset #49451
Extend stacktrace for failed tests not directly under testset #49451
Conversation
…-test-stacktraces
…-test-stacktraces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fantastic work, @serenity4, this is a very welcome improvement.
This looks ready to me. One question, though: lookup
is expensive, and to me it looks like it's possible to call lookup
on the backtrace twice. If it's a problem (not sure it is), a potential solution is to cache the result. To determine if this matters, have you timed how long Julia's own test suite takes with this change vs the implementation currently on master?
A quick profiling indicates that most of the time of is indeed spent in |
I reduced a bunch of potentially duplicated lookups, but there were very few and I did not notice performance improvements in practice. Nevertheless, I think the implementation is slightly cleaner so I'd leave it with the refactors. The slow part is actually looking up stackframes all the way until the I don't think we can really improve performance without trying to further optimize |
LGTM. Just need to fix the |
Should be all good now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sgtm
Thanks for the review @timholy and @vtjnash! And thanks to @Seelengrab who pointed me to the right direction :) |
I think this is a great step towards making julia testsuites more modular, by making the stacktraces of failed cases easily readable :) Thanks for implementing this! |
I noticed this PR seems to break something like MRE would be:
Before:
Now:
Note that we now have an internal error within Test.jl |
Thanks for reporting this, it seems like originally this case was also not well supported (see how it includes frames until One quick fix would be to remove the type assertions and be more relaxed, to avoid errors from occurring. For a better fix, we might want to take a look at why no macro expansions are present in the stacktrace in the first place, and then see how easily we could change that. I'll take a deeper look this evening and make a PR with either of the fixes depending on how it goes. |
Ref #44757 |
From #35360 (comment) it seems like that is not going to be easy, so I decided to go with the simpler fix for now in #49633. |
After #44995
vs. before
notice we now have the missing |
Issue
When tests are factored out into functions, the stacktrace for failed or errored
@test
s only includes the frames related to the macrocall inside that function, discarding frames higher up. Because information about the callsite of such testing functions is not preserved, it makes finding failing tests much harder as there is no line indicating where the function was called. This is especially inconvenient when these testing functions are called in multiple places.Basic example:
Stacktrace on master
As one can see, the stacktraces give no clue about where to look besides that testing function.
Stacktrace on this PR
This is more informative. Note that we include 3 additional frames instead of just one; that is due to inlining which groups these 3 frames into one stacktrace index. This makes the stacktrace more verbose, so we will have to make sure that we only include more frames when necessary.
Proposed implementation
The solution implemented in this PR improves backtrace scrubbing such that if the source location of a
@test
macrocall is not directly in scope of an outer@testset
macrocall, then all frames higher up until a testset is reached are included.