-
Notifications
You must be signed in to change notification settings - Fork 386
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
Exclude code that follows [DoesNotReturn] from code coverage (per #898) #904
Exclude code that follows [DoesNotReturn] from code coverage (per #898) #904
Conversation
…t follow calls to methods that never return to be excluded from coverage metrics. Determines what methods will return with [DoesNotReturn], though that is configurable. Adds a test that explores a few "odd" patterns. There are a number of open questions: - Preferred way to punch configuration of this attribute in? - Test suite is really fragile, especially around multiple tests locking each other out of the same files - is there a better way to run them? - Reachability does not distinguish between "unreachable because of method call" and "unreachable because the IL is actually unreachable" * The compiler is... disinclined to produce unreachable IL, but this is a real (potentially) significant change - Related, reachability is always calculated and used - should it be ignored if there are no calls to [DoesNotReturn] methods? - "Odder" unconditional branches are not handled (leave, leave_s, jmp, etc.) yet - Naming and code layout things * There are several new classes (mostly nested), where should these go? * There's yet-another-block-class, what should it be named? Are there existing classes that can be used instead? Finally, there are performance concerns. Current approach doesn't go wild with allocations or an insane number of passes or anything, but could probably be improved.
So these failures are much easier to understand than what I was seeing locally. Appears that this @MarcoRossignoli maybe I should be treating corelib specially? Or is there something else I should consider. |
Poking around a little more, the root issue seems to be that I'm trying to resolve a type that is defined in a module that is being actively instrumented. I think if I instead build a list of Will see if I can get that hacked up in the next day or two. |
… before we start instrumenting them. Trying to do it in the same pass inevitably leads to issues with Resolve. Also adds tests for generic methods and generic types, which were not functional before. Has been tested against https://github.com/kevin-montrose/Cesil , and confirmed to work.
…e that gracefully and log as a warning. Also log when methods are first found to not return
Ultimately ended up doing a read-only pass over a module before instrumentation starts to avoid any need to call There's still a chance that resolving fails (if, for example, the assembly referenced cannot be found). This seems to happen in some integrations tests, which might just be an error in their configuration (seen in these logs). I chose to assume those methods always return - whether that is correct is debatable. Relevant logic is here if it should change. I expanded the new test case to include generic methods and methods on generic types, which did not work in my first pass at this. I've also run this against the personal project that prompted #898, and confirmed this PR addresses my original issue: |
Thanks again Kevin I'm on vacation this weeks I'll take a look asap 🙇 |
You mean a way to opt-out in case of bugs?At the moment we don't have settings for coverage engine...ops sorry we have new one added last PR only to skip autoprops(but it's related to needs of user to avoid a % increase decrease for autoprops, make sense). Btw could be better avoid too much flags, are you concerned about some ambiguity on some custom user
To test in local usually works well
Btw for testing you should add some tests like in file https://github.com/coverlet-coverage/coverlet/pull/904/files#diff-b0c2dc6aa3b37bd4720bfeea133be676 (I pushed a file sample to speedup)
I think we should apply only in case of call to
Ok
Create a new file under
I'm ok with it...we have other place with that problem and an open issue #836 |
…rather than mixing and matching) and remove _most_ LINQ (clarifies some code, and performs a little better).
…ssary to support Leave(_S) in the non-exception cases, since it's legal for the compiler to emit those in a try{} even if they don't "leave".
…s an unconditional branch (in the same way these other terms are branches, anyway).
…otReturn] methods
…ontrose/coverlet into exclude-unreachable-code
…he TestReachabilityHelper test working in VS.
Took a little longer than I'd hoped @MarcoRossignoli , but I've caught this PR back up to master and made some changes.
I tried to follow the pattern I saw with taking the attribute names explicitly into I'll take a look at the SkipAutoProps commit and see if I can puzzle out the last mile. It seems reasonable to allow the same flexibility with these attributes as is allowed with the others.
I have implemented this behavior - I now bail out early if no calls to
In testing, I found it was actually really important to implement support for Leave and Leave_S. Without support everything around So I did implement them, and ended up implementing The remaining "weird" instructions I can think of are
I have moved everything into the file
Alright, good to know. I did a little bit of de-LINQ-ing and just general cleanup (mostly unifying on immutable collections, instead of mixing immutable and mutable collections), so hopefully I'm not making things too much worse. |
…r commandline and msbuild use.
Took a whack at the settings and documentation. Seems to work for me, but I am not very well versed in dotnet tools, msbuild, or customizing VS test runners so I'm not very confident in that. |
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.
Some nits but here we go.
I need to take another deep review loop on reachability helper, do some integration test(for new parameters usually I did a manual test to be sure that values flow correctly, but in future we'll add also automatic integration) and after that we can merge.
Thanks a lot!
Co-authored-by: Marco Rossignoli <[email protected]>
Co-authored-by: Marco Rossignoli <[email protected]>
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.
Thanks and sorry for the delay 🙇 busy summer
Per #898
Implementing reachability analysis, which will allow instructions that follow calls to methods that never return to be excluded from coverage metrics.
Determines what methods will return with [DoesNotReturn], though that is configurable.
Adds a test that explores a few "odd" patterns.
Though this seems to work, there are a few open questions:
dotnet build-server shutdown
(with copious direct killing of dotnet and MSBuild process that VS spins up) and there are still some tests (likeCoverlet.Core.Instrumentation.Tests.InstrumenterTests.TestInstrumentCoreLib
) that just will not runFinally, there are performance concerns. Current approach doesn't go wild with allocations or an insane number of passes or anything, but could probably be improved.