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

Compatibility Issue with .NET Core 3.1 and .NET 6.0: System.Reflection.TargetInvocationException #66

Open
sethkhon opened this issue Jul 13, 2023 · 13 comments

Comments

@sethkhon
Copy link

I am encountering an issue when attempting to use the ReportPortalLogger with .NET Core 3.1 and .NET 6.0.

My application is a simple test project that uses the ReportPortalLogger for test logging. The tests run without problems under .NET Framework 4.6.2. However, when attempting to run the same tests under .NET Core 3.1 or .NET 6.0, I encounter a System.Reflection.TargetInvocationException during the instantiation of the ReportPortalLogger.

Here is the error message:
System.IO.FileLoadException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

I've tried to diagnose the issue and it seems to be related to a mismatch or incompatibility between the 'System.Runtime' assembly version that the application is trying to load and the version expected by the ReportPortalLogger or one of its dependencies.

I also noted a similar issue when using NUnit.Console.Runner with .NET Core 3.1 and .NET 6.0, suggesting a broader compatibility issue with .NET Core/.NET 6.0.

I'd appreciate any guidance or assistance you can provide. Are there known compatibility issues with .NET Core/.NET 6.0 or specific features or APIs that the ReportPortalLogger depends on that might not be fully compatible with .NET Core/.NET 6.0?

Thank you for your assistance.

@nvborisenko
Copy link
Member

@sethkhon it's quite strange to see this issue, everything works fine on my end. To go further with issue investigation, I would ask to create a simple test project to reproduce the issue and share with us. So many factors may be a reason, even Microsoft Test SDK. So let's start from simple reproducible project.

@sethkhon
Copy link
Author

@nvborisenko Thank you very much for your prompt response! I have uploaded a simple project, including a pdf showing the command execution and result:
https://github.com/sethkhon/testUpload/tree/main/TestTemplatesH1

@nvborisenko
Copy link
Member

Before diving deeper into the issue, let me ask you: "Does it make sense to use complex command to execute tests"?

I am asking, because simple dotnet test -l:reportportal works without issues.

Read more aboit it:
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-vstest

It works, because dotnet tool is smart enough to automatically determine .net runtime version for your test project.

@sethkhon
Copy link
Author

@nvborisenko ,
Thank you for your assistance! I can confirm that the 'dotnet test' command works with .NET Core 3.1. I have yet to try it with .NET 6.0.

I appreciate your guidance towards the 'dotnet test' command. However, I would like to share some feedback based on my experience. I have been using the 'vstest.console.exe' command for the past eight years in my test automation scripts without any issues. I suspect that you might have also used it successfully in the early stages of your development of the agent.

I was not familiar with 'dotnet test' and had not heard of it prior to this. When I saw it listed second in the agent execution instruction, I assumed it was an alternative method, not necessarily a simpler one. From a syntax perspective, based on the instruction, they didn't appear significantly different.

I believe that users could benefit from more definitive instructions. If the instructions clearly stated that the preferred method is 'dotnet test' and that 'vstest.console.exe' should be used only if the user has a specific need for it, it would provide more clarity.

Thank you for your understanding and for your continued support.

Best regards,
@sethkhon

@nvborisenko
Copy link
Member

The world is changing, we are aimed to support more as possible. RP for vstest is a plugin, we are loaded by vstest. If dotnet test works, then RP ream is happy.

When we see vstest.console.exe ... /testadapterpath:".../" then you better know what you do.

In any case vstest.console.exe is not a guy who we can blame, I think testadapterpath is a reason. I don't want to dive deeper, dotnet test work fine :)

Feel free to create new issue, or even create new issue for vstest.

@Rudy2308
Copy link

System.Reflection.TargetInvocationException During the run on VS2022 using Test Explorer and TargetFramework net8.0

[7/17/2024 3:23:11.673 AM] [Error] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileLoadException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) at ReportPortal.VSTest.TestLogger.ReportPortalLogger..ctor() --- End of inner exception stack trace --- at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework.TestPluginManager.CreateTestExtension[T](Type extensionType) in /_/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginManager.cs:line 76 at Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework.Utilities.LazyExtension2.get_Value() in //src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs:line 106
at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.TestLoggerManager.InitializeLoggerByUri(Uri uri, Dictionary2 parameters) in /_/src/Microsoft.TestPlatform.CrossPlatEngine/Client/TestLoggerManager.cs:line 367 at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.TestLoggerManager.Initialize(String runSettings) in /_/src/Microsoft.TestPlatform.CrossPlatEngine/Client/TestLoggerManager.cs:line 171 at Microsoft.VisualStudio.TestPlatform.Client.TestPlatform.CreateTestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteria, TestPlatformOptions options, Dictionary2 sourceToSourceDetailMap, IWarningLogger warningLogger) in /
/src/Microsoft.TestPlatform.Client/TestPlatform.cs:line 112
at Microsoft.VisualStudio.TestPlatform.CommandLine.TestPlatformHelpers.TestRequestManager.RunTests(IRequestData requestData, TestRunCriteria testRunCriteria, ITestRunEventsRegistrar testRunEventsRegistrar, TestPlatformOptions options, Dictionary2 sourceToSourceDetailMap) in /_/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs:line 1260 at Microsoft.VisualStudio.TestPlatform.CommandLine.TestPlatformHelpers.TestRequestManager.RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLauncher3 testHostLauncher, ITestRunEventsRegistrar testRunEventsRegistrar, ProtocolConfig protocolConfig) in /_/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs:line 380 at Microsoft.VisualStudio.TestPlatform.Client.DesignMode.DesignModeClient.<>c__DisplayClass28_0.<StartTestRun>b__0() in /_/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs:line 486

Dotnet test works but I do need the option to run tests via Test Explorer and see results in RP

@VladimirNilov
Copy link

VladimirNilov commented Jul 20, 2024

@nvborisenko Hi not sure if .net6.0 was inside the dotnet-client at the time when the issue was reported or not, but right now the same issue is coming from here .net6.0 in the target

additionally, if we redirect binding for System.Runtime, we will get into "Could not load type 'System.AppDomain'" issue as, the class is located in another lib for netframework

looks like if we keep .net target in any of the parent/child projects, it's not possible to load via the vstest.console.exe and consequently to run the tests with the added adapter via VS2022

Could we please remove the support of the test run in Visual Studio and use the vstest.console.exe in the readme as it's not working and cannot be working right now. Thank you

@nvborisenko
Copy link
Member

I believe we can mitigate it. We should understand under which framework we are running (.net framework 4.8?!). The issue here is about that runner cannot dependencies. The best way to mitigate it is to ask vstest team about best practices to write custom loggers with external dependdecies. @VladimirNilov are you interested to ask it?

@VladimirNilov
Copy link

@nvborisenko, thank you for taking your time and looking into this.
Probably before addressing this question to them, I'd like to know your thoughts about the case with the System.Text.Json lib. It has System.Runtime.CompilerServices.Unsafe dependency. And in the case, if we remove .net6.0 target (migrate to netframework), it's still not working for vstest.console.exe without an additional redirect of the binding to the newVersion="6.0.0.0" for the System.Runtime.CompilerServices.Unsafe

It can be easily done and works fine after adding the binding, but the config files go directly from vstest.console.exe and should be manually changed. (Not sure if they admit to adding the changes in their repo for the binding)

@nvborisenko
Copy link
Member

We are trying to provide our external dependencies here:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
Probably we can play with it, at least here we can add more "logging" around to see which dependency we couldn't resolve.

@VladimirNilov
Copy link

@nvborisenko got the idea, will check it later and provide the update. Thank you

@nvborisenko
Copy link
Member

From theoretical perspective, if test project is targeted to .net8 then assemblies from .net8 tree are copied to output (bin/Debug). And when we are ran under vstest.console.exe (.net48?!) we resolve incorrect assemblies.

@VladimirNilov
Copy link

VladimirNilov commented Jul 23, 2024

@nvborisenko hey again,
I'd thought the same, but got the exception for the 'System.Runtime.CompilerServices.Unsafe, is trying to find Version=4.0.4.1, with net48 for libs and .net8.0 for the tests.proj
Additionally, if I update System.Text.Json to 8.0.4 I start getting the System.Runtime is trying to find 8.0.0.0


Thanks to your message, I just put the unsafe resolver in the shared resolver and it works fine without the additional changes in the vstest.console.exe.json config file
for netstandard2.0

    <TargetFrameworks>netstandard2.0</TargetFrameworks>
    <LangVersion>preview</LangVersion>
    <NullableReferenceTypes>true</NullableReferenceTypes>
      private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        if (new AssemblyName(args.Name).Name == "System.Runtime.CompilerServices.Unsafe")
        {
            return typeof(System.Runtime.CompilerServices.Unsafe).Assembly;
        }
        return args.Name.StartsWith("System.Text.Json", StringComparison.OrdinalIgnoreCase) 
            ? Assembly.Load("System.Text.Json") : null;
    }

for net482 it also works but additionally it's a new question for System.Net.Http version, so I just used an old one that is compatible without additional code changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants