stryker-mutator / stryker-net

Mutation testing for .NET core and .NET framework!
https://stryker-mutator.io
Apache License 2.0
1.75k stars 176 forks source link

Unhandled exception in solution mode with multiple target frameworks #2812

Closed tommysor closed 6 months ago

tommysor commented 6 months ago

Describe the bug Given:

Then: Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key 'TargetDir' was not present in the dictionary.

Repro: https://github.com/tommysor/TestStryker13_1 Comment/uncomment TargetFramework[s] in TestStryker.Tests.csproj and/or TestStryker.csproj

Possibly same problem as https://github.com/stryker-mutator/stryker-net/issues/1899 (so maybe already resolved in master)

Logs This log is from using <TargetFrameworks> in TestStryker.Tests.csproj.

debug output @tommysor ➜ /workspaces/TestStryker13_1 (main) $ dotnet stryker --verbosity debug [.. snip ascii art ..] [13:15:36 INF] Logging enabled at level Debug Version: 3.13.0 [13:15:36 DBG] Stryker started with options: {"MsBuildPath": null, "DevMode": false, "ProjectPath": "/workspaces/TestStryker13_1", "IsSolutionContext": true, "WorkingDirectory": "/workspaces/TestStryker13_1", "OutputPath": "/workspaces/TestStryker13_1/StrykerOutput/2023-12-31.13-15-36", "ReportPath": "/workspaces/TestStryker13_1/StrykerOutput/2023-12-31.13-15-36/reports", "ReportFileName": "mutation-report", "SolutionPath": "/workspaces/TestStryker13_1/TestStryker.sln", "TargetFramework": null, "LogOptions": {"LogToFile": false, "LogLevel": "Debug", "$type": "LogOptions"}, "MutationLevel": "Standard", "Thresholds": {"High": 80, "Low": 60, "Break": 0, "$type": "Thresholds"}, "AdditionalTimeout": 5000, "LanguageVersion": "Default", "Concurrency": 1, "SourceProjectName": "", "TestProjects": [], "TestCaseFilter": "", "Reporters": ["Progress", "Html"], "WithBaseline": false, "BaselineProvider": "Disk", "AzureFileStorageUrl": "", "AzureFileStorageSas": "", "DashboardUrl": "https://dashboard.stryker-mutator.io", "DashboardApiKey": null, "Since": false, "SinceTarget": "master", "DiffIgnoreChanges": [], "FallbackVersion": "master", "ModuleName": "", "ReportTypeToOpen": null, "Mutate": [{"Glob": {"Tokens": [{"TrailingPathSeparator": {"Value": "/", "$type": "PathSeparatorToken"}, "LeadingPathSeparator": null, "$type": "WildcardDirectoryToken"}, {"$type": "WildcardToken"}], "$type": "Glob"}, "IsExclude": false, "TextSpans": [{"Start": 0, "End": 2147483647, "Length": 2147483647, "IsEmpty": false, "$type": "TextSpan"}], "$type": "FilePattern"}], "IgnoredMethods": [], "ExcludedMutations": [], "ExcludedLinqExpressions": [], "OptimizationMode": "CoverageBasedTest", "ProjectName": "", "ProjectVersion": "", "BreakOnInitialTestFailure": false, "$type": "StrykerOptions"} [13:15:37 INF] Analysis starting. [13:15:37 INF] Identifying projects to mutate in /workspaces/TestStryker13_1/TestStryker.sln. This can take a while. [13:15:37 DBG] Analyzing 2 projects. [13:15:37 DBG] Analyzing TestStryker/TestStryker.csproj [13:15:37 DBG] Analyzing TestStryker.Tests/TestStryker.Tests.csproj [13:15:40 DBG] Analysis of project TestStryker/TestStryker.csproj succeeded. [13:15:40 DBG] Analysis of project TestStryker.Tests/TestStryker.Tests.csproj succeeded. [13:15:40 INF] Found 1 source projects [13:15:40 INF] Found 1 test projects [13:15:40 DBG] Matched TestStryker/TestStryker.csproj to 1 test projects: [13:15:40 DBG] /workspaces/TestStryker13_1/TestStryker.Tests/TestStryker.Tests.csproj [13:15:41 DBG] Skipping auto-generated code file: /workspaces/TestStryker13_1/TestStryker/obj/Debug/netstandard2.0/.NETStandard,Version=v2.0.AssemblyAttributes.cs [13:15:41 DBG] Skipping auto-generated code file: /workspaces/TestStryker13_1/TestStryker/obj/Debug/netstandard2.0/TestStryker.AssemblyInfo.cs [13:15:41 INF] Found project /workspaces/TestStryker13_1/TestStryker/TestStryker.csproj to mutate. [13:15:41 INF] Analysis complete. [13:15:41 INF] Building solution TestStryker.sln [13:15:41 DBG] Started initial build using dotnet build [13:15:41 DBG] Initial build using path: /workspaces/TestStryker13_1/TestStryker.sln [13:15:50 DBG] Initial build successful [13:15:50 INF] Time Elapsed 00:00:13.8040578 Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key 'TargetDir' was not present in the dictionary. at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at Stryker.Core.Initialisation.Buildalyzer.IAnalyzerResultExtensions.GetAssemblyDirectoryPath(IAnalyzerResult analyzerResult) at Stryker.Core.Initialisation.Buildalyzer.IAnalyzerResultExtensions.GetAssemblyPath(IAnalyzerResult analyzerResult) at Stryker.Core.Initialisation.InitialisationProcess.DiscoverTests(SourceProjectInfo projectInfo, ITestRunner testRunner) at Stryker.Core.Initialisation.InitialisationProcess.InitialTest(StrykerOptions options, SourceProjectInfo projectInfo, ITestRunner testRunner, Boolean throwIfFails) at Stryker.Core.Initialisation.InitialisationProcess.GetMutationTestInputs(StrykerOptions options, IReadOnlyCollection`1 projects, ITestRunner runner) at Stryker.Core.Initialisation.ProjectOrchestrator.MutateProjects(StrykerOptions options, IReporter reporters, ITestRunner runner)+MoveNext() 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) at Stryker.CLI.StrykerCli.RunStryker(IStrykerInputs inputs) in /_/src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 102 at Stryker.CLI.StrykerCli.<>c__DisplayClass11_0.b__0() in /_/src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 74 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 80 at Stryker.CLI.Program.Main(String[] args) in /_/src/Stryker.CLI/Stryker.CLI/Program.cs:line 14

Log is slightly different when using <TargetFrameworks> in TestStryker.csproj, but I believe that is a different symptom from the same source problem (see "Additional context").

alternate debug output @tommysor ➜ /workspaces/TestStryker13_1 (main) $ dotnet stryker --verbosity debug [.. snip ascii art ..] [13:47:37 INF] Logging enabled at level Debug Version: 3.13.0 [13:47:37 DBG] Stryker started with options: {"MsBuildPath": null, "DevMode": false, "ProjectPath": "/workspaces/TestStryker13_1", "IsSolutionContext": true, "WorkingDirectory": "/workspaces/TestStryker13_1", "OutputPath": "/workspaces/TestStryker13_1/StrykerOutput/2023-12-31.13-47-37", "ReportPath": "/workspaces/TestStryker13_1/StrykerOutput/2023-12-31.13-47-37/reports", "ReportFileName": "mutation-report", "SolutionPath": "/workspaces/TestStryker13_1/TestStryker.sln", "TargetFramework": null, "LogOptions": {"LogToFile": false, "LogLevel": "Debug", "$type": "LogOptions"}, "MutationLevel": "Standard", "Thresholds": {"High": 80, "Low": 60, "Break": 0, "$type": "Thresholds"}, "AdditionalTimeout": 5000, "LanguageVersion": "Default", "Concurrency": 1, "SourceProjectName": "", "TestProjects": [], "TestCaseFilter": "", "Reporters": ["Progress", "Html"], "WithBaseline": false, "BaselineProvider": "Disk", "AzureFileStorageUrl": "", "AzureFileStorageSas": "", "DashboardUrl": "https://dashboard.stryker-mutator.io", "DashboardApiKey": null, "Since": false, "SinceTarget": "master", "DiffIgnoreChanges": [], "FallbackVersion": "master", "ModuleName": "", "ReportTypeToOpen": null, "Mutate": [{"Glob": {"Tokens": [{"TrailingPathSeparator": {"Value": "/", "$type": "PathSeparatorToken"}, "LeadingPathSeparator": null, "$type": "WildcardDirectoryToken"}, {"$type": "WildcardToken"}], "$type": "Glob"}, "IsExclude": false, "TextSpans": [{"Start": 0, "End": 2147483647, "Length": 2147483647, "IsEmpty": false, "$type": "TextSpan"}], "$type": "FilePattern"}], "IgnoredMethods": [], "ExcludedMutations": [], "ExcludedLinqExpressions": [], "OptimizationMode": "CoverageBasedTest", "ProjectName": "", "ProjectVersion": "", "BreakOnInitialTestFailure": false, "$type": "StrykerOptions"} [13:47:37 INF] Analysis starting. [13:47:37 INF] Identifying projects to mutate in /workspaces/TestStryker13_1/TestStryker.sln. This can take a while. [13:47:37 DBG] Analyzing 2 projects. [13:47:37 DBG] Analyzing TestStryker/TestStryker.csproj [13:47:37 DBG] Analyzing TestStryker.Tests/TestStryker.Tests.csproj [13:47:40 DBG] Analysis of project TestStryker/TestStryker.csproj succeeded. [13:47:41 DBG] Analysis of project TestStryker.Tests/TestStryker.Tests.csproj succeeded. [13:47:41 INF] Found 1 source projects [13:47:41 INF] Found 1 test projects [13:47:41 DBG] Matched TestStryker/TestStryker.csproj to 1 test projects: [13:47:41 DBG] /workspaces/TestStryker13_1/TestStryker.Tests/TestStryker.Tests.csproj [13:47:41 INF] Analysis complete. [13:47:41 INF] Time Elapsed 00:00:03.5380233 Unhandled exception. System.NotSupportedException: Specified method is not supported. at Stryker.Core.Initialisation.InputFileResolver.GetProjectComponentBuilder(Language language, StrykerOptions options, SourceProjectInfo projectInfo) at Stryker.Core.Initialisation.InputFileResolver.BuildSourceProjectInfo(StrykerOptions options, IAnalyzerResult analyzerResult, IEnumerable`1 analyzerResults) at Stryker.Core.Initialisation.InputFileResolver.BuildProjectInfos(StrykerOptions options, IReadOnlyDictionary`2 dependents, IReadOnlyCollection`1 projectsUnderTestAnalyzerResult, IReadOnlyCollection`1 testProjects) at Stryker.Core.Initialisation.InputFileResolver.ResolveSourceProjectInfos(StrykerOptions options) at Stryker.Core.Initialisation.InitialisationProcess.GetMutableProjectsInfo(StrykerOptions options) at Stryker.Core.Initialisation.ProjectOrchestrator.MutateProjects(StrykerOptions options, IReporter reporters, ITestRunner runner)+MoveNext() 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) at Stryker.CLI.StrykerCli.RunStryker(IStrykerInputs inputs) in /_/src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 102 at Stryker.CLI.StrykerCli.<>c__DisplayClass11_0.b__0() in /_/src/Stryker.CLI/Stryker.CLI/StrykerCLI.cs:line 74 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 80 at Stryker.CLI.Program.Main(String[] args) in /_/src/Stryker.CLI/Stryker.CLI/Program.cs:line 14

Expected behavior Run Stryker without error. Expected behavior is present in Stryker Version: 3.12.0

Desktop (please complete the following information):

Additional context Seems to be caused by missing values in IAnalyzerResult.Properties.

Failling either here: https://github.com/stryker-mutator/stryker-net/blob/70adc60caad193ed6942ee970ea5373003ade4e4/src/Stryker.Core/Stryker.Core/Initialisation/Buildalyzer/IAnalyzerResultExtensions.cs#L20-L20

Or here: https://github.com/stryker-mutator/stryker-net/blob/70adc60caad193ed6942ee970ea5373003ade4e4/src/Stryker.Core/Stryker.Core/Initialisation/InputFileResolver.cs#L371-L390

Indirectly: https://github.com/stryker-mutator/stryker-net/blob/70adc60caad193ed6942ee970ea5373003ade4e4/src/Stryker.Core/Stryker.Core/Initialisation/Buildalyzer/IAnalyzerResultExtensions.cs#L130-L135

rouke-broersma commented 6 months ago

Do you have any hints as to what we should use instead of TargetDir?

rouke-broersma commented 6 months ago

This should be fixed by #2811

Your repro works with latest master, and does not work with the commit before that pull request was merged.