Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhandled exception in solution mode with multiple target frameworks #2812

Closed
tommysor opened this issue Dec 31, 2023 · 2 comments
Closed

Unhandled exception in solution mode with multiple target frameworks #2812

tommysor opened this issue Dec 31, 2023 · 2 comments
Labels
🐛 Bug Something isn't working

Comments

@tommysor
Copy link
Contributor

Describe the bug
Given:

  • Stryker Version: 3.13.0
  • Running in Solution file context
  • When project and/or test project is using the plural <TargetFrameworks> tag in .csproj.
    As opposed to the singular <TargetFramework> tag.
    Does not need to actually have multiple targeted frameworks to trigger error.

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 #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.Dictionary2.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, IReadOnlyCollection1 projects, ITestRunner runner)
at Stryker.Core.Initialisation.ProjectOrchestrator.MutateProjects(StrykerOptions options, IReporter reporters, ITestRunner runner)+MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 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, IEnumerable1 analyzerResults) at Stryker.Core.Initialisation.InputFileResolver.BuildProjectInfos(StrykerOptions options, IReadOnlyDictionary2 dependents, IReadOnlyCollection1 projectsUnderTestAnalyzerResult, IReadOnlyCollection1 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.List1..ctor(IEnumerable1 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):

  • OS: Debian GNU/Linux 12 (bookworm) (mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm)
  • Type of project: core
  • Framework Version: net8.0
  • Stryker Version: 3.13.0

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

Failling either here:

public static string GetAssemblyDirectoryPath(this IAnalyzerResult analyzerResult) => FilePathUtils.NormalizePathSeparators(analyzerResult.Properties["TargetDir"]);

Or here:

private ProjectComponentsBuilder GetProjectComponentBuilder(
Language language,
StrykerOptions options,
SourceProjectInfo projectInfo) => language switch
{
Language.Csharp => new CsharpProjectComponentsBuilder(
projectInfo,
options,
_foldersToExclude,
_logger,
FileSystem),
Language.Fsharp => new FsharpProjectComponentsBuilder(
projectInfo,
options,
_foldersToExclude,
_logger,
FileSystem),
_ => throw new NotSupportedException($"Language not supported: {language}")
};

Indirectly:

public static Language GetLanguage(this IAnalyzerResult analyzerResult) => analyzerResult.GetPropertyOrDefault("Language") switch
{
"F#" => Language.Fsharp,
"C#" => Language.Csharp,
_ => Language.Undefined,
};

@tommysor tommysor added the 🐛 Bug Something isn't working label Dec 31, 2023
@rouke-broersma
Copy link
Member

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

@rouke-broersma
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants