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

Unable to load DLL 'wpfgfx_cor3.dll' or one of its dependencies during unit test #1328

Open
Ql1m4xx opened this issue Mar 14, 2023 · 11 comments

Comments

@Ql1m4xx
Copy link

Ql1m4xx commented Mar 14, 2023

Description:
currently we are migrating our Windows Application (WPF) from .NET Framework 4.8 to .NET 6.
We are using NUnit to test our user interface but we are getting the error that the 'wpfgfx_cor3.dll' could not be loaded

Stacktrace:

  1. Error : Productnamespace.GUIFoundation.Test.ControlTests.ExtendedControl.ExtendedControlTests.BaseElementViewModelTest
    System.DllNotFoundException : Unable to load DLL 'wpfgfx_cor3.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)
    at MS.Win32.PresentationCore.UnsafeNativeMethods.MILFactory2.CreateFactory(IntPtr& ppIFactory, UInt32 SDKVersion)
    at System.Windows.Media.FactoryMaker..ctor()
    at System.Windows.Media.StreamAsIStream.IStreamFrom(IntPtr memoryBuffer, Int32 bufferSize)
    at System.Windows.Media.Imaging.BitmapDecoder.GetIStreamFromStream(Stream& bitmapStream)
    at System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
    at System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
    at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
    at System.Windows.Media.Imaging.BitmapImage.EndInit()
    at System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource, RequestCachePolicy uriCachePolicy)
    at System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource)
    at Productnamespace.GUIFoundation.Test.ControlTests.ExtendedControl.ExtendedControlTests.SetUp() in C:\Git\Repos\Product\Libraries\GUIFoundation\Sources\GuiFoundation.Test\ControlTests\ExtendedControl\ExtendedControlTests.cs

It's the same issue like #1319

The workaround to adjust the nunit-agent.runtimeconfig.json is not feasible for us because we dont want to adjust the "installed" file that comes with the NUnit.Console

Used Version: 3.16.2

Thanks for your help in advance

@OsirisTerje
Copy link
Member

Does it work with 3.15.2 ?

@Ql1m4xx
Copy link
Author

Ql1m4xx commented Mar 14, 2023

Does it work with 3.15.2 ?

I got not the same problem with version 3.15.2

  1. Invalid : C:/Git/Repos/Product/Libraries/GUIFoundation/Sources/GuiFoundation.Test/bin/Debug/Product.GUIFoundation.Test.dll
    Unable to load one or more of the requested types.
    Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationCore, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationCore, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.

@OsirisTerje
Copy link
Member

OsirisTerje commented Mar 14, 2023

Ok, then I assume it doesn't work with using dotnet test either?

It would also be great if you could provide a very small repro for this.

@spkl
Copy link

spkl commented Mar 14, 2023

Hi OsirisTerje, I have created a repository with a repro for this: https://github.com/spkl/nunit-console-1328-repro
The test shows and then closes a dialog from a WPF library. I have pasted the results from dotnet test and the two discussed NUnit Console versions as a readme.

I'm on the same dev team as Ql1m4xx. This is not a perfect repro for our scenario, as we are also using a third-party library (DevExpress), but the errors seem to be comparable for now. Thanks for looking into this.

@OsirisTerje
Copy link
Member

@spkl @Ql1m4xx Thanks for the repro. I can confirm I do see the same. It works when using Visual Studio (2022) and it works using dotnet test, either on csproj or directly on the test dll.

I'll summarize the results that I see:

Visual Studio 2022, it works:
image

dotnet test , project level , it works
image

dotnet test nunit-console-1328-test.dll, in the bin folder, It works:
image

All of these use the adapter version 4.2.1 (which has the engine 3.15.2 built-in)

It fails with the nunit console (version 3.15.2, and @spkl show it fails with 3.16.2 too)
image

As @CharliePoole have pointed out earlier, the assembly loading with the adapter is done by the MS testhost, and not the engine, whereas the console will do the loading itself. So that's where it struggles:

Thanks again, we can use this to start working on it.

@CharliePoole Any suggestions? (and yes, I have read the other stuff on this, so let's start from that.)
@rprouse Rings any bells?

@carstencodes
Copy link

carstencodes commented Mar 15, 2023

I might have one additional clue.

The Microsoft Test SDK generates an entrypoint into each test assembly. It can be seen from any reflector like ILspy or dotpeek.
The entrypoint is called from the runtime, which is selected using a runtime.config.json in version and experience/workload.

Hence the unit test is simply deriving from Microsoft.NET.SDK, the resulting runtime should be NetCoreApp, hence a simple console application.
As the assembly under test actively uses WPF and this is executed during the test, it must use the WindowsDesktop runtime.

Hence adding

<UseWPF>true</UseWPF>

to the csproj of the unit test will actually enforce the runtime to select the WindowsDesktop App, which provides the WPF runtime libraries.

This way, the test should run.

@spkl @Ql1m4xx Can you please give it a try?

@spkl
Copy link

spkl commented Mar 15, 2023

@carstencodes nunit-console-1328-test.runtimeconfig.json already contains Microsoft.NETCore.App and Microsoft.WindowsDesktop.App. I've tried adding UseWPF, but it changes nothing.
If I remember correctly from other issues, NUnit Console does not evaluate the runtimeconfig.json of a test assembly.

@carstencodes
Copy link

@spkl Yeah, but it lead me on the right track.

I had to run

$ COREHOST_TRACE=1 dotnet test 2> dotnet-test.corehost_trace.txt
...
$ COREHOST_TRACE=1 dotnet nunit  nunit-console-1328-test/bin/Debug/net6.0-windows/nunit-console-1328-test.dll 2> dotnet-nunit.corehost_trace.txt

and diff the resulting files to actually find it.

The target runtime is not determined by the test assembly but in this case by the starting process.

I replaced

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "rollForward": "Major",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "6.0.0"
    },
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false
    }
  }
}

with

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "rollForward": "Major",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "6.0.0"
      },
      {
        "name": "Microsoft.WindowsDesktop.App",
        "version": "6.0.0"
      }
    ],
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false
    }
  }
}

in the nunit-console's runtime config json file.

The result was:

$ dotnet nunit nunit-console-1328-test/bin/Debug/net6.0-windows/nunit-console-1328-test.dll
NUnit Console 3.16.2 (Release)
Copyright (c) 2022 Charlie Poole, Rob Prouse
Mittwoch, 15. März 2023 08:46:01

Runtime Environment
   OS Version: Microsoft Windows 10.0.19044
  Runtime: .NET 6.0.14

Test Files
    nunit-console-1328-test/bin/Debug/net6.0-windows/nunit-console-1328-test.dll


Run Settings
    DisposeRunners: True
    WorkDirectory: C:\git\external\github\nunit-console-1328-repro
    NumberOfTestWorkers: 12

Test Run Summary
  Overall result: Passed
  Test Count: 1, Passed: 1, Failed: 0, Warnings: 0, Inconclusive: 0, Skipped: 0
  Start time: 2023-03-15 07:46:02Z
    End time: 2023-03-15 07:46:08Z
    Duration: 6.272 seconds

Results (nunit3) saved as TestResult.xml

Hence, in order to support additional frameworks like WPF-Test, XUnit-STA, FlaUI or XAMLTest, it might be a good idea to create a desktop-runtime runner for these cases.
(It cannot be added to the regular runtime as it might actually break linux/mac support).

@rprouse
Copy link
Member

rprouse commented Mar 15, 2023

This is great info @carstencodes ,thanks for the work you put into it

@OsirisTerje
Copy link
Member

@carstencodes @spkl @Ql1m4xx May I just ask: What is the reason you need to use NUnit.Console and not just use dotnet test?

@Ql1m4xx
Copy link
Author

Ql1m4xx commented Mar 16, 2023

@OsirisTerje We are using NUnit.Console since 10 or more years to execute more than 10k tests with it. We parse the result and display it and it worked very well in the last decade.
A switch to dotnet test for us is not a thing that we can do over night.
We would highly appreciate that NUnit.Console supports us and I think other users, too, with a solution that dont requires the change of installed files.

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

5 participants