Closed AndyCC25 closed 10 months ago
thanks for opening this issue. This obviously should not happen.
We will look into this.In the meantime, I think I have a workaround for you:
could you please add the following stryker comments // Stryker disable once all
like this:
// Stryker disable once all
AccountNumber.ValueChanged += RefreshAccountNumber;
And any similar lines that may cause this issue. This should prevent this issue. I think we may need a bit more info to dig into this, we will revert to you if this is confirmed.
Confirm I need a bit more info: could you please share the method which contains this line?
AccountNumber.ValueChanged += RefreshAccountNumber;
According to the stack trace, it looks an expression body method. This should not be a problem of course, I am simply looking for how to reproduce this issue.
Sure it is inside a Blazor component and inside one of the methods of the lifecycle like this
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
AccountNumber.ValueChanged += RefreshAccountNumber;
}
JIC Something that I'm seeing using the workaround is that it happens in the places where besides having the +=
usually in these components I'm doing the unsubscribe too in the dispose method like AccountNumber.ValueChanged -= RefreshAccountNumber;
Good news, I reproduced your issue. But this is a different line. Look for this construct:
SomeMetho() => AccountNumber.ValueChanged += RefreshAccountNumber;
And add the stryker comments I gave you.
The bit of code you provided works properly. Note that this implies there is another workaround: using a statement body (i.e. in brackets) instead of a statement body should fix your problem.
Meanwhile I will see how to correct this.
Do you mean this:
public void OnDispose()
{
AccountNumber.ValueChanged -= ValueChanged
}
instead of this public void OnDispose() => AccountNumber.ValueChanged -= ValueChanged;
exactly
sorry: I did not reproduce, I introduced a syntax error that triggered the problem, but it should not happen in the wild. Still searching. Will report when I am sure I reproduced it.
if you need help trying to reproduce this one, I also notice that is happening in my Blazor components when I have a .razor and .razor.cs files for a component
[13:46:50 WRN] Safe Mode! Stryker will try to continue by rolling back all mutations in method. This should not happen, please report this as an issue on github with the previous error message.
[13:46:50 WRN] Stryker.NET encountered a compile error in C:\test\src\Test\BudgetGroupMaintenance.razor.cs (at 27:32) with message: 'BudgetGroupMaintenance.OnInitialized()': no suitable method found to override (Source code: protected override void OnInitialized()
Thanks for the details. I have a working theory for why it fails. But first things first: with my workaround are you able to go through the Stryker session? Does it run properly ? I am not sure what the current status is with Blazor projects, but they were not supported in the past. I am pretty sure things have improved now that Stryker have preliminary support for code generators, but it may fail for many reasons, including failing to run said code generators.
This error; no suitable method found to override (Source code: protected override void OnInitialized()
, is unlikely to be triggered by a mutation, as mutations do not alter method signature. I suspect it comes from some failing with Blazor generated code that was not generated.
As this is a compilation error that encompasses the whole method, Stryker tries to remove every mutations in it (a.k.a Safe Mode). But it turns out that Stryker had to convert the method from expression body to statement body so it is able to mutate it.
And the exception happens because Stryker attemps to transform the method back to expression body, but it sill has mutations in it, hence it cannot be transformed legally. As said earlier, this does not happen during 'regular' run, because this kind of error cannot happen with regular mutations.
I will see how to secure the mutations removal process for such a situation, to avoid an unpleasant exception, but I am afraid this will not solve your whole problem.
No, with the workaround the stryker session is not completed due the errors that appear about the no suitable method found to override
but I pass all those errors about the expression methods, Would be nice to do something here so that would help to run stryker over projects with blazor, If I can do something extra to help you, I'm available
Thanks for the feedback. On my side, I have a 'fix' for your original problem. Regarding the problem with code generators: 1) Next Stryker release will provide details when Stryker fails to load a generator. It can help solve the problem locally and/or help us improve Stryker (if possible) in that regard 2) You have some details about this in issue #2736
Do you know when is gonna be the next release?
Hoping to release today
When running the dotnet stryker in my project is throwing an exception like the following
Unhandled exception. System.InvalidOperationException: Can't extract original expression from {if(StrykerR4Z2rUyYtnj4mXU.MutantControl.IsActive(126)){AccountNumber.ValueChanged += RefreshAccountNumber;}else{AccountNumber.ValueChanged -= RefreshAccountNumber;}} at Stryker.Core.Instrumentation.ExpressionMethodToBodyEngine.Revert(BaseMethodDeclarationSyntax node) in /_/src/Stryker.Core/Stryker.Core/Instrumentation/ExpressionMethodToBodyEngine.cs:line 55
The code where is that one is like this
All the logs are like this
[09:18:43 INF] Time Elapsed 00:02:04.3443519 Unhandled exception. System.InvalidOperationException: Can't extract original expression from {if(StrykerR4Z2rUyYtnj4mXU.MutantControl.IsActive(126)){AccountNumber.ValueChanged += RefreshAccountNumber;}else{AccountNumber.ValueChanged -= RefreshAccountNumber;}} at Stryker.Core.Instrumentation.ExpressionMethodToBodyEngine.Revert(BaseMethodDeclarationSyntax node) in //src/Stryker.Core/Stryker.Core/Instrumentation/ExpressionMethodToBodyEngine.cs:line 55 at Stryker.Core.Instrumentation.BaseEngine`1.RemoveInstrumentation(SyntaxNode node) in //src/Stryker.Core/Stryker.Core/Instrumentation/BaseEngine.cs:line 47 at Stryker.Core.Mutants.MutantPlacer.RemoveMutant(SyntaxNode nodeToRemove) in //src/Stryker.Core/Stryker.Core/Mutants/MutantPlacer.cs:line 121 at Stryker.Core.Compiling.RollbackProcess.RemoveMutations(SyntaxTree originalTree, IEnumerable`1 diagnosticInfo) in //src/Stryker.Core/Stryker.Core/Compiling/RollbackProcess.cs:line 205 at Stryker.Core.Compiling.RollbackProcess.Start(CSharpCompilation compiler, ImmutableArrayb_0() in //src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 68
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.<>c DisplayClass143_0.b_0(CancellationToken )
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
at Stryker.CLI.StrykerCli.Run(String[] args) in //src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 74
at Stryker.CLI.Program.Main(String[] args) in //src/Stryker.CLI/Stryker.CLI/Program.cs:line 14
1 diagnostics, Boolean lastAttempt, Boolean devMode) in /_/src/Stryker.Core/Stryker.Core/Compiling/RollbackProcess.cs:line 56 at Stryker.Core.Compiling.CsharpCompilingProcess.TryCompilation(Stream ms, Stream symbolStream, CSharpCompilation compilation, EmitResult previousEmitResult, Boolean lastAttempt, Int32 retryCount) in /_/src/Stryker.Core/Stryker.Core/Compiling/CsharpCompilingProcess.cs:line 135 at Stryker.Core.Compiling.CsharpCompilingProcess.Compile(IEnumerable
1 syntaxTrees, Stream ilStream, Stream symbolStream) in //src/Stryker.Core/Stryker.Core/Compiling/CsharpCompilingProcess.cs:line 83 at Stryker.Core.MutationTest.CsharpMutationProcess.CompileMutations(MutationTestInput input) in //src/Stryker.Core/Stryker.Core/MutationTest/CsharpMutationProcess.cs:line 87 at Stryker.Core.MutationTest.CsharpMutationProcess.Mutate(MutationTestInput input) in //src/Stryker.Core/Stryker.Core/MutationTest/CsharpMutationProcess.cs:line 76 at Stryker.Core.MutationTest.MutationTestProcess.Mutate() in //src/Stryker.Core/Stryker.Core/MutationTest/MutationTestProcess.cs:line 88 at Stryker.Core.Initialisation.ProjectMutator.MutateProject(StrykerOptions options, MutationTestInput input, IReporter reporters) in //src/Stryker.Core/Stryker.Core/Initialisation/ProjectMutator.cs:line 38 at Stryker.Core.Initialisation.ProjectOrchestrator.MutateProjects(StrykerOptions options, IReporter reporters, ITestRunner runner)+MoveNext() in //src/Stryker.Core/Stryker.Core/Initialisation/ProjectOrchestrator.cs:line 62 at System.Collections.Generic.List1..ctor(IEnumerable
1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Stryker.Core.StrykerRunner.RunMutationTest(IStrykerInputs inputs, ILoggerFactory loggerFactory, IProjectOrchestrator projectOrchestrator) in //src/Stryker.Core/Stryker.Core/StrykerRunner.cs:line 61 at Stryker.CLI.StrykerCli.RunStryker(IStrykerInputs inputs) in //src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 93 at Stryker.CLI.StrykerCli.<>cDisplayClass10_0.I've tried to avoid the possible tests that are using that logic but still is failing to run those mutations