coverlet: Code coverage stops working if assembly contains interfaces from source generators

_Originally posted as https://github.com/reactiveui/refit/issues/1073_

Describe the bug

In a project using Refit 6.0.8 and coverlet.msbuild 3.0.2, upon updating from Refit 5.2.4, code coverage is no longer being collected for the assembly containing Refit interfaces.

Using coverlet’s troubleshooting guide here, I narrowed my investigation down to this line of interest:

[coverlet] Unable to instrument module: C:\Coding\Projects\MyProject\tests\MyProject.Tests\bin\debug\net5.0\MyProject.dll, pdb without local source files, [C:\Coding\Projects\MyProject\src\MyProject\InterfaceStubGenerator.Core\Refit.Generator.InterfaceStubGenerator\IMyApi.g.cs]

As there’s no file on disk here, that sort of makes sense, but causes an issue as it breaks all code coverage for the project for the sake of the one interface.

I’m guessing this is something to do with the usage of source generators in Refit.

The failure then slipped through several CI jobs for Refit updates until it was noticed due to https://github.com/coverlet-coverage/coverlet/issues/1083.

Steps To Reproduce

Clone https://github.com/martincostello/alexa-london-travel and run ./build.ps1.

The build script will eventually output something like this:

+--------+------+--------+--------+
| Module | Line | Branch | Method |
+--------+------+--------+--------+

+---------+------+--------+--------+
|         | Line | Branch | Method |
+---------+------+--------+--------+
| Total   | 100% | 100%   | 100%   |
+---------+------+--------+--------+
| Average | NaN% | NaN%   | NaN%   |
+---------+------+--------+--------+

Example build: https://github.com/martincostello/alexa-london-travel/runs/1869767942?check_suite_focus=true#step:4:78

This seems to be affecting multiple repos I have using Refit, not just this one.

Here’s another example: https://github.com/martincostello/alexa-london-travel-site/runs/1870035564?check_suite_focus=true#step:4:160

Expected behavior

Assemblies containing Refit interfaces are instrumented correctly.

For the referenced repository, it should output something like this from build.ps1:

+--------------------+-------+--------+--------+
| Module             | Line  | Branch | Method |
+--------------------+-------+--------+--------+
| LondonTravel.Skill | 99.1% | 94.82% | 97.9%  |
+--------------------+-------+--------+--------+

+---------+-------+--------+--------+
|         | Line  | Branch | Method |
+---------+-------+--------+--------+
| Total   | 99.1% | 94.82% | 97.9%  |
+---------+-------+--------+--------+
| Average | 99.1% | 94.82% | 97.9%  |
+---------+-------+--------+--------+

Example build: https://github.com/martincostello/alexa-london-travel/runs/1869465349?check_suite_focus=true#step:4:80

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 30 (11 by maintainers)

Most upvoted comments

Thanks Marco ❤️

Will this also fix the coverlet.console? @MarcoRossignoli

Yep the engine in shared between “drivers”

I got confused between you and Marco. 😃

Martin is now a coverlet maintainer specialized in “alpha testing” 😄 so it’s ok you ask to him(joking)

I’m more concerned that the class/module consuming the generator is no longer covered due to the fact a source generator is being used

Coverlet skip by default all dlls doesn’t have a corresponding local source files. In this way we don’t need to ask to users to filter out not interesting code.

I know you previously said a release would be made asap, is there a rough ETA. Not rushing you, just planning is all.

This week end I’ll release this fix, I’m trying to add also another update but I don’t know if I’ll make it.

@martincostello Thanks for the info

You’re probably hitting this issue then. The fix will be in either preview 6 or preview 7. https://github.com/dotnet/runtime/pull/53275

Your suggestion to change the source generated to use “source-filename.g” (the “.cs” is appended automatically by C# source generators) works using 3.0.3-preview.4 @martincostello . Thanks for your help.

I know you previously said a release would be made asap, is there a rough ETA. Not rushing you, just planning is all.

Ah, I see your point now. Sorry. It hadn’t occurred to me that coverlet was tripping up “because” of the file name. I’ll change the demo and see if 3.0.3-preview.4 fixes it. Thanks @martincostello .

Cool I’ll release the fix asap

Sure - I’ll take a look a bit later today. Thanks for digging into it 🙂

Thanks a Martin! You’re amazing! This weekend I’ll tackle this issue, super busy week ☹️ until now.

I’ve created a small repo here you can use to try and debug the issue: https://github.com/martincostello/coverlet-refit-repro

If you clone it and run build.ps1 it will output an msbuild.binlog file.

Below is screenshot showing the [coverlet] output.

On my laptop the two most relevant lines are:

[coverlet] Unable to instrument module: C:\Coding\martincostello\coverlet-refit-repro\Project2.Tests\bin\Debug\net5.0\Project1.dll, pdb without local source files, [C:\Coding\martincostello\coverlet-refit-repro\Project1\InterfaceStubGenerator.Core\Refit.Generator.InterfaceStubGenerator\IGitHub.g.cs]
[coverlet] Unable to instrument module: C:\Coding\martincostello\coverlet-refit-repro\Project2.Tests\bin\Debug\net5.0\Project2.dll, pdb without local source files, [C:\Coding\martincostello\coverlet-refit-repro\Project2\InterfaceStubGenerator.Core\Refit.Generator.InterfaceStubGenerator\Generated.g.cs]

image

ok thank you, I need to investigate.

I’ve tried a few different combinations, but it doesn’t seem to work.

<ExcludeByFile>**/*.g.cs</ExcludeByFile>

From the .binlog:

[coverlet] Excluded source files filter '**/*.g.cs'
...
[coverlet] Unable to instrument module: C:\Coding\Projects\MyProject\tests\MyProject.Tests\bin\debug\net5.0\MyProject.dll, pdb without local source files, [C:\Coding\Projects\MyProject\src\MyProject\InterfaceStubGenerator.Core\Refit.Generator.InterfaceStubGenerator\Generated.g.cs]