stryker-net icon indicating copy to clipboard operation
stryker-net copied to clipboard

Stryker fails when running against .NET 5 Azure Function

Open richparker288 opened this issue 3 years ago • 23 comments

Describe the bug When running Stryker against a .NET 5 Azure Function with the Microsoft.Azure.Functions.Worker.Sdk package referenced we get the following exception:

Unhandled exception. System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\XXXXX\XXXX.XXXXX\XXXXX\StrykerAzFunctionRepro\StrykerAzFunctionRepro\obj\Release\netcoreapp3.1\WorkerExtensions.AssemblyInfo.cs'.

Version: 1.0.1

[14:15:10 INF] Stryker will use a max of 4 parallel testsessions.
[14:15:10 INF] Identifying project to mutate.
A new version of Stryker.NET (1.2.2) is available. Please consider upgrading using `dotnet tool update -g dotnet-stryker`

A preview version of Stryker.NET (1.2.2) is available.
If you would like to try out this preview version you can install it with `dotnet tool update -g dotnet-stryker --version 1.2.2`
Since this is a preview feature things might not work as expected! Please report any findings on GitHub!

[14:15:12 INF] The project C:\XXXX\XXXX.XXXXX\XXXXX\StrykerAzFunctionRepro\StrykerAzFunctionRepro\StrykerAzFunctionRepro.csproj will be mutated.
[14:15:14 INF] Time Elapsed 00:00:04.0508342
Unhandled exception. System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\XXXXX\XXXX.XXXXX\XXXXX\StrykerAzFunctionRepro\StrykerAzFunctionRepro\obj\Release\netcoreapp3.1\WorkerExtensions.AssemblyInfo.cs'.
at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)
at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.StreamReader.ValidateArgsAndOpenPath(String path, Encoding encoding, Int32 bufferSize)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks)
at System.IO.File.InternalReadAllText(String path, Encoding encoding)
at System.IO.File.ReadAllText(String path)
at System.IO.Abstractions.FileWrapper.ReadAllText(String path)
at Stryker.Core.Initialisation.CsharpProjectComponentsBuilder.FindProjectFilesUsingBuildalyzer(IAnalyzerResult analyzerResult, StrykerOptions options) in /_/src/Stryker.Core/Stryker.Core/Initialisation/CsharpProjectComponentsBuilder.cs:line 99
at Stryker.Core.Initialisation.CsharpProjectComponentsBuilder.Build() in /_/src/Stryker.Core/Stryker.Core/Initialisation/CsharpProjectComponentsBuilder.cs:line 40
at Stryker.Core.Initialisation.InputFileResolver.ResolveInput(StrykerOptions options) in /_/src/Stryker.Core/Stryker.Core/Initialisation/InputFileResolver.cs:line 77
at Stryker.Core.Initialisation.InitialisationProcess.Initialize(StrykerOptions options) in /_/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs:line 64
at Stryker.Core.Initialisation.ProjectMutator.MutateProject(StrykerOptions options, IReporter reporters) in /_/src/Stryker.Core/Stryker.Core/Initialisation/ProjectMutator.cs:line 30
at Stryker.Core.Initialisation.ProjectOrchestrator.MutateProjects(StrykerOptions options, IReporter reporters)+MoveNext() in /_/src/Stryker.Core/Stryker.Core/Initialisation/ProjectOrchestrator.cs:line 61
at System.Collections.Generic.List`1..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
59
at Stryker.CLI.StrykerCli.RunStryker(IStrykerInputs inputs) in /_/src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 90
at Stryker.CLI.StrykerCli.<>c__DisplayClass9_0.<Run>b__0() in /_/src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 65
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.<>c__DisplayClass146_0.<OnExecute>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 71
at Stryker.CLI.Program.Main(String[] args) in /_/src/Stryker.CLI/Stryker.CLI/Program.cs:line 15

Logs log-20220112.txt

Expected behavior Stryker tests are executed

Desktop (please complete the following information):

  • OS: Windows
  • Type of project: Azure Function
  • Framework Version: .NET 5
  • Stryker Version: 1.0.1 (same error occurs with version 1.2.2)

Additional Context As soon as the package Microsoft.Azure.Functions.Worker.Sdk is removed, the tests run fine.

richparker288 avatar Jan 12 '22 14:01 richparker288

Looks like a generated file WorkerExtensions.AssemblyInfo.cs is available during buildalyzer analysis but missing afterwards causing us to not be able to read this file. It might be enough to skip *.AssemblyInfo.cs files if they cannot be found on disk. If that does not work this might have to be fixed in upstreams buildalyzer.

rouke-broersma avatar Jan 21 '22 13:01 rouke-broersma

I'm having the same issue with .NET 6 and isolated functions. How can I configure it to skip that WorkerExtensions.AssemblyInfo.cs file?

mlouage avatar Feb 23 '22 08:02 mlouage

Is there an update to this or are there any workarounds we can use in the meantime? Thanks.

JJ-288 avatar Jun 15 '22 10:06 JJ-288

Is the problem still present with the latest version? Is there any chance we can get a project to reproduce this issue ?

dupdob avatar Jun 15 '22 12:06 dupdob

Is the problem still present with the latest version? Is there any chance we can get a project to reproduce this issue ?

Apologies for the delayed response. Yes, this was tested against the latest version. Will try and find time to get a sanitized project to replicate the problem.

JJ-288 avatar Jun 22 '22 12:06 JJ-288

Hi, I have the same issue with .NET 6.0 isolated function

function.csproj

` <Project Sdk="Microsoft.NET.Sdk">

net6.0 v4 Exe
<AnalysisMode>AllEnabledByDefault</AnalysisMode>

<UserSecretsId>eb4984ff-b68e-46de-91ab-cda4f2e350a4</UserSecretsId>
`

Can you please check how to solve it as even exclude of WorkerExtensions.AssemblyInfo.cs not working for me or I'm doing it not right.

Thanks!

rodchenkov avatar Jun 25 '22 13:06 rodchenkov

StrykerReplication.zip

Attached a dummy project with test - enough to replicate the issue on 2.0.0

JJ-288 avatar Jun 30 '22 08:06 JJ-288

thanks for the project. I did reproduce this issue. The missing WorkerExtensions.AssemblyInfo.cs file is just the tip of the iceberg: it seems that Buildalyzer completely fails for this project. Indeed, WorkerExtensions.AssemblyInfo.cs is the ONLY found source file (according to Buildalyzer).

dupdob avatar Jun 30 '22 08:06 dupdob

@richardwerkman : I see you are the author of those lines https://github.com/stryker-mutator/stryker-net/blob/f67f96fbd413b6f62c0c34d68107b4cbbc0e79de/src/Stryker.Core/Stryker.Core/Initialisation/ProjectFileReader.cs#L69-L72 but with this project here, we clearly have a true failure... do you remember when/why Stryker assumes everything will work even if Buildalyzer fails.

dupdob avatar Jun 30 '22 09:06 dupdob

Yes. Buildalyzer seemed to return success false sometimes even though it provided all project info we needed and our intitial build step succeeded. So it seemed like a bug in Buildalyzer to me. Since stryker had no trouble continuing the run I decided to log a debug statement but ignore the failed Buildalyzer step.

That was quite some time ago, so things might have changed since then.

richardwerkman avatar Jun 30 '22 09:06 richardwerkman

I have some progress, but I fear I am in a dead end: I have been able to properly extract the source files (out the AnalyzerResults), but I still have troubles with the project references which are not resolved. I may be able to hack around this. But this appears to be a Buildalyzer issue/limitations. I am afraid the problem needs to be addressed there.

dupdob avatar Jul 06 '22 19:07 dupdob

I have some progress, but I fear I am in a dead end: I have been able to properly extract the source files (out the AnalyzerResults), but I still have troubles with the project references which are not resolved. I may be able to hack around this. But this appears to be a Buildalyzer issue/limitations. I am afraid the problem needs to be addressed there.

Did you have any luck with a potential work around or does this need to be raised separately?

JJ-288 avatar Jul 28 '22 08:07 JJ-288

Has an issue been raised on the Buildalyzer side? If so, could it be linked here?

Cosmin-Apopei avatar Jul 28 '22 15:07 Cosmin-Apopei

@JJ-288 : I am afraid I stopped pursuing this strategy. I realized I was working around one of BuildAlyzer's issues and this was turning in a wild goose chase: everytime I fixed a problem, another one appeared. @Cosmin-Apopei : not that I am aware of. Most of my current Stryker devoted time is spent on a new feature, so I did not have the opportunity to create a reproducing project for the BuildAlyzer team to work upon.

looking at azure functions project, I realized those rely heavily on custom build steps. As such, there is a high risk that Stryker will not be able to handle those even if Buildalyzer's issue(s?) is fixed.

dupdob avatar Jul 29 '22 09:07 dupdob

I have created an issue in the Buildalyzer project https://github.com/daveaglick/Buildalyzer/issues/210 with an example project based on the example project for this bug

bonner-earle avatar Jul 29 '22 15:07 bonner-earle

looking at azure functions project, I realized those rely heavily on custom build steps

This is the key. Buildalyzer runs MSBuild (I.e. dotnet build) while instrumenting the build with a custom logger that pipes events back to Buildalyzer for analysis. Those events usually follow a known pattern which means we can use them to pick up on things like which files were involved in the build (in that case by looking for the call MSBuild makes to the .NET compiler and parsing the command line involved).

Basically, all bets are off if someone instruments MSBuild in a way that it deviates too much from expectations. MSBuild itself is a "program" and so creating a tool that can process all possible MSBuild behaviors is impossible, because the range of possible behaviors is infinite.

That said, we may be able to special-case the tasks and targets that Azure Functions adds to continue reporting source files, assuming (and this is a big assumption) they're in the logs at all. I've seen other MSBuild tasks that "eat" things like source files because they go off and do their own compilation or processing totally outside the normal MSBuild flow of calling csc. Still looking at this specific case in https://github.com/daveaglick/Buildalyzer/issues/210 to see if Buildalyzer can support it - but no promises at this point.

daveaglick avatar Aug 24 '22 20:08 daveaglick

I believe I had similar problem in DevOps pipeline. It's a .NET 6 WebApp project. I build the solution with dotnet build - This produces the right DLLs Property TargetFramework: net6.0 Property MSBuildSemanticVersion=17.3.2+561848881 Property CompilerApiVersion=roslyn4.3

Then I run the dotnet Stryker which runs Buildalyzer I guess? And the DLLs seem to disappear? (it uses the same settings as dotnet build task)

✅ Here is what helped me in the end!

{
    "stryker-config":
    {
        ~"solution": "../../My.Solution.sln",
        "project": "MyProject.csproj",
        "verbosity": "trace"
    }
}

All I had to do is remove the reference to the solution file and it started working 😃 For some reason when it was building it through the solution file it lost the references and didn't build the whole project? Pointing it at the project alone seemed to resolve the right references and build everything.

jakubtrebacz-dev avatar Nov 15 '22 12:11 jakubtrebacz-dev