coverlet-coverage / coverlet

Cross platform code coverage for .NET
MIT License
2.97k stars 386 forks source link

Coverlet flagging a branch for an async functions finally block where none exists #1337

Open bdurrani opened 2 years ago

bdurrani commented 2 years ago

I have the following class

namespace CovetletTest;

public record Data(int One, string Two);
public class DoerOfStuff
{
   private readonly ILogger<DoerOfStuff> _log;

   public DoerOfStuff(ILogger<DoerOfStuff> log)
   {
      _log = log;
   }

   public void StartWithoutWaiting(Data data)
   {
      Task.Run(() => ActualWork(data));
   }

   private async Task ActualWork(Data data)
   {
      var (one, two) = data;
      try
      {

         var res = one++;
         _log.LogInformation($"Res {res}");
      }
      catch(Exception exception)
      {
        _log.LogError(exception, "Something bad happened"); 
      }
      finally
      {
         _log.LogInformation("I'm finally here");
         string filePath = "simple.txt";
         string text = $"Hello World";

         await File.WriteAllTextAsync(filePath, text);
      } 
   }
}

When using coverlet, it is flagging the finally block for that class with a branch that doesn't exist

image

Not sure what is going on here. This is a .net 6 project. I've attach a test project with the smallest reproduct I could find.

CovetletTest.zip

MarcoRossignoli commented 2 years ago

Unfortunately that branches exist are emitted by Roslyn to handle the async/await state machine, in coverlet we try to elide looking for IL patterns. Look like we're failing here.