Skip to content

Improving removal attempts of mutations when compile fails. #3542

@iamwyza

Description

@iamwyza

Describe the bug

(couldn't decide if this was a feature or a bug....)

Right now, when stryker creates a mutation on a file that causes a compilation error, it will attempt to rollback mutations until it finds the one that failed. However, one extremely common case that I see that causes failures is the statement removal on throw. However, because throwing is frequently towards the end of a method, and it appears that stryker works through the mutations from the top down when attempting to remove them, it will frequently run out of mutations to roll back before failing. (at least I think it rolls the back from earliest to latest in it's attempt to find the offending mutation).

Logs
I don't have a log file that I can share since it contains proprietary code; if we really need one, I can create a sample project that exemplifies this.

Expected behavior

Ideally, there should be some special rules (if they don't already exist) that looks for common patterns that would cause this failure. In this case, it would be exceptionally common for the removal of a throw block to cause a CS0161 error during compilation.

Desktop (please complete the following information):

  • OS: Windows and Linux
  • Type of project: Core
  • Framework Version: 10
  • Stryker Version 4.14.0

Additional context

The current workaround is to have to annotate that throw with a stryker disable, but ideally we wouldn't need to do that anywhere that we're re-throwing at the end of a method.

An contrived example; needs to have enough mutations in it that it never gets to undoing the throw removal.

public bool TestMethod() {
      if (_thing1 == thing2) { return true; }
      if (_thing2 == thing2) { return true; }
      if (_thing3 == thing2) { return true; }
      if (_thing4 == thing2) { return true; }
      if (_thing5 == thing2) { return true; }
      if (_thing6 == thing2) { return true; }
      if (_thing7 == thing2) { return true; }
      if (_thing8 == thing2) { return true; }
      if (_thing9 == thing2) { return true; }
  
      if (_thing10 == _thing1) {
          return false;
      }

      // Stryker disable once Statement
      throw new NotFoundException("whoops");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    🐛 BugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions