nunit / nunit-console

NUnit Console runner and test engine
MIT License
215 stars 151 forks source link

System.TypeInitializationException: The type initializer for 'NUnit.Engine.Internal.TestAssemblyResolver' threw an exception: System.ArgumentNullException: Value cannot be null. (Parameter 'path1') #1351

Open Jens-G opened 1 year ago

Jens-G commented 1 year ago

Test started via

nunit3-console.exe .\bin\mytestassembly.dll

Eventlog

EntryType          : Error
InstanceId         : 1026
Message            : Application: dotnet.exe
                     CoreCLR Version: 7.0.122.56804
                     .NET Version: 7.0.1
                     Description: The process was terminated due to an unhandled exception.
                     Exception Info: NUnit.Engine.NUnitEngineException: An exception occurred in the driver while loading tests.
                      ---> System.TypeInitializationException: The type initializer for 'NUnit.Engine.Internal.TestAssemblyResolver' threw an exception.
                      ---> System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
                        at System.ArgumentNullException.Throw(String paramName)
                        at System.IO.Path.Combine(String path1, String path2, String path3)
                        at NUnit.Engine.Internal.TestAssemblyResolver..cctor()
                        --- End of inner exception stack trace ---
                        at NUnit.Engine.Internal.TestAssemblyResolver..ctor(AssemblyLoadContext loadContext, String assemblyPath)
                        at NUnit.Engine.Internal.TestAssemblyLoadContext..ctor(String testAssemblyPath)
                        at NUnit.Engine.Drivers.NUnitNetCore31Driver.Load(String assemblyPath, IDictionary`2 settings)
                        at NUnit.Engine.Runners.DirectTestRunner.LoadDriver(IFrameworkDriver driver, String testFile, TestPackage subPackage)
                        --- End of inner exception stack trace ---
                        at NUnit.Engine.Runners.DirectTestRunner.LoadDriver(IFrameworkDriver driver, String testFile, TestPackage subPackage)
                        at NUnit.Engine.Runners.DirectTestRunner.LoadPackage()
                        at NUnit.Engine.Runners.DirectTestRunner.EnsurePackageIsLoaded()
                        at NUnit.Engine.Runners.DirectTestRunner.RunTests(ITestEventListener listener, TestFilter filter)
                        at NUnit.Engine.Runners.AbstractTestRunner.Run(ITestEventListener listener, TestFilter filter)
                        at NUnit.Engine.Communication.Transports.Tcp.TestAgentTcpTransport.CommandLoop()
                        at System.Threading.Thread.StartCallback()
OsirisTerje commented 1 year ago
  1. Which NUnit-console version are you using?
  2. Can you create small repro?
Jens-G commented 1 year ago

NUnit Console 3.16.3 (Release) Copyright (c) 2022 Charlie Poole, Rob Prouse Dienstag, 18. Juli 2023 14:35:54

Not sure, since it only crashes on one machine ...

I already checked the dotnet install paths because I recognized that GetDotnetInstallDirectory() might return a null path but that seems not the issue ... at least the settings on both machines are identical in that regard.

At the moment I ran out of ideas TBH.

manfred-brands commented 1 year ago

Looking at the code that seems to be the place where the null must come from. Is one machine 32-bit or is the ninit-console somehow set to 32-bit only?

Jens-G commented 1 year ago

The test assembly was set to x86 (for whatever reason), changed to AnyCPU that solved at least the actual issue at hand. But maybe the error message could be improved? Just a suggestion.

Anyway, thanks for the help!

manfred-brands commented 1 year ago

But maybe the error message could be improved

I agree. A check if the path is not null and exists would result in a better error message

CharliePoole commented 1 year ago

It looks like the error is in the use of statics initialized in lines 26-28 of TestAssemblyResolver. Even though the class is only built for .NET Core 3.1 or higher, GetAssemblyResolver checks whether the process is running in 32-bit mode and may return null in that case. The following statement then fails.

However, I think an error message at this point would be inappropriate because it's possible for any of the three statics to be null and calling code needs to check. For example...

In retrospect, we should probably have methods to query whether each component is installed rather than relying on a null result to indicate their absence.

MohammadNsr commented 1 year ago

I have the same error in my project. When i am running it on some Testservers i have got this error, but locally on my PC and on other PC's I am not getting this error. What could be here the cause?

NUnit.Engine.NUnitEngineException: An exception occurred in the driver while loading tests. ---> System.TypeInitializationException: The type initializer for 'NUnit.Engine.Internal.TestAssemblyResolver' threw an exception. ---> System.ArgumentNullException: Value cannot be null. (Parameter 'path1') at System.IO.Path.Combine(String path1, String path2, String path3) at NUnit.Engine.Internal.TestAssemblyResolver..cctor() --- End of inner exception stack trace --- at NUnit.Engine.Internal.TestAssemblyResolver..ctor(AssemblyLoadContext loadContext, String assemblyPath) at NUnit.Engine.Internal.TestAssemblyLoadContext..ctor(String testAssemblyPath) at NUnit.Engine.Drivers.NUnitNetCore31Driver.Load(String assemblyPath, IDictionary`2 settings) at NUnit.Engine.Runners.DirectTestRunner.LoadDriver(IFrameworkDriver driver, String testFile, TestPackage subPackage) --- End of inner exception stack trace --- at NUnit.Engine.Runners.DirectTestRunner.LoadDriver(IFrameworkDriver driver, String testFile, TestPackage subPackage) at NUnit.Engine.Runners.DirectTestRunner.LoadPackage() at NUnit.Engine.Runners.DirectTestRunner.EnsurePackageIsLoaded() at NUnit.Engine.Runners.DirectTestRunner.Explore(TestFilter filter) at NUnit.Engine.Runners.MasterTestRunner.Explore(TestFilter filter) at TestRunner_Core.RunTest(String testClass, TextWriter outWriter) in D:\Jenkins\workspace\src\nortico\test\TestRunner_Core.cs:line 831

here is a part of my project file:

<PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
 </PropertyGroup>

  <ItemGroup>
    <Reference Include="nunit.engine">
      <HintPath>$(ROOT)\make\dotnet\OpenSource\NUnit\nunit.engine.3.16.3\lib\netcoreapp3.1\nunit.engine.dll</HintPath>
    </Reference>
    <Reference Include="nunit.engine.api">
      <HintPath>$(ROOT)\make\dotnet\OpenSource\NUnit\nunit.engine.3.16.3\lib\netcoreapp3.1\nunit.engine.api.dll</HintPath>
    </Reference>
    <Reference Include="nunit.engine.core">
      <HintPath>$(ROOT)\make\dotnet\OpenSource\NUnit\nunit.engine.3.16.3\lib\netcoreapp3.1\nunit.engine.core.dll</HintPath>
    </Reference>
    <Reference Include="nunit.framework">
      <HintPath>$(ROOT)\make\dotnet\OpenSource\NUnit\nunit.3.13.3\lib\netstandard2.0\nunit.framework.dll</HintPath>
    </Reference>
    <Reference Include="System.Configuration.ConfigurationManager">
      <HintPath>$(ROOT)\make\dotnet\Microsoft\system.configuration.configurationmanager\5.0.0\lib\netstandard2.0\System.Configuration.ConfigurationManager.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson">
      <HintPath>$(ROOT)\make\dotnet\Microsoft\microsoft.aspnetcore.mvc.newtonsoftjson\5.0.5\lib\net5.0\Microsoft.AspNetCore.Mvc.NewtonsoftJson.dll</HintPath>
    </Reference>
  </ItemGroup>

any idea how to fix this??

CharliePoole commented 1 year ago

See my comment on 8 July

MohammadNsr commented 1 year ago

Hello Charlie,

I checked your comment, and I don't see any reason on the server which is giving the error:

here is output of the runtimes existing on this server C:>dotnet --list-runtimes Microsoft.AspNetCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

both are 64x processes.

on my local machine, where no problems occuring i have the following: C:>dotnet --list-runtimes Microsoft.AspNetCore.App 3.1.31 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.31 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.31 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

could the different versions be the cause of the error?

MohammadNsr commented 1 year ago

Hello again, i solved the problem in creating the key "Path" in the registry because it should be found in the function GetDotNetInstallDirectory() in nunit-console/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyResolver.cs

private static string GetDotNetInstallDirectory() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Running on Windows so use registry RegistryKey key = Environment.Is64BitProcess ? Registry.LocalMachine.OpenSubKey(@"Software\dotnet\SetUp\InstalledVersions\x64\sharedHost\") : Registry.LocalMachine.OpenSubKey(@"Software\dotnet\SetUp\InstalledVersions\x86\sharedHost\"); return (string)key?.GetValue("Path"); } else return "/usr/shared/dotnet/"; }

the value is the home directory of dotnet. in my case it was C:\Program Files\dotnet\