Build/Test Issues

MSTest AssemblyInitialize

Started by Paramethod on 1,983 views

Hello NCrunch,

I'm using the MSTest AssemblyInitialize to subscribe to AppDomain.CurrentDomain.AssemblyResolve to dynamically load either x86 or x64 dlls at runtime (See http://stackoverflow.com/a/9951658 for implementation details). In Visual Studio Test Explorer, all those tests run correctly and the assembly resolve event is hit and loads the correct dll file. With NCrunch, all tests relying to a dynamically loaded dll fails with an error like this:

System.IO.FileNotFoundException: Could not load file or assembly 'MyLibrary.x86.dll' or one of its dependencies. The specified module could not be found.
File name: 'MyLibrary.x86.dll'
at MyTestLibrary.TheTest()

Anything I could do to have NCrunch work with that test scenario?

Thanks,

Alex
Hi Alex,

Thanks for posting.

My first guess here is that this issue may be related to the logic being used to resolve the location of the required assembly. Are you using a relative path to find MyLibrary.x86.dll in your assembly resolve event? If so, the path may be different when working under the NCrunch workspace. See implicit file dependencies for more details.

Are you able to get a breakpoint to work on your AssemblyResolve or AssemblyInitialize code under NCrunch?

Note that a simpler alternative to using AssemblyResolve might be to simply force the assembly to load into the domain in your initialize/setup code using Assembly.LoadFrom. Generally once an assembly is loaded into the application domain, .NET won't try to resolve it again and will used the loaded version only.

If you're using this to try and load Native assemblies from projects in your solution, you might want to look into the copied project dependencies config setting.
Hi Remco,

Thank you for your solutions, unfortunately I cannot debug the test or force load the libraries in initialize. I was only looking at the failed test node error, and it seems the failure is not at the test level, but at the test project level. Here's the 'Analysis failure' error for that test project:

An error occurred while analysing this project after it was built: System.IO.FileNotFoundException: Could not load file or assembly 'MyAssembly.x86, Version=0.0.0.0, Culture=neutral, PublicKeyToken=222' or one of its dependencies. The specified module could not be found.
File name: 'MyAssembly.x86, Version=0.0.0.0, Culture=neutral, PublicKeyToken=222' ---> System.IO.FileNotFoundException: Could not load file or assembly 'MyAssembly.x86.dll' or one of its dependencies. The specified module could not be found.
File name: 'MyAssembly.x86.dll'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at nCrunch.Common.CustomAssemblyResolver.resolveAssemblyFrom(IEnumerable`1 possibleAssemblyPaths, ParsedAssemblyName parsedAssemblyName)
at nCrunch.Common.CustomAssemblyResolver.ResolveAssembly(ParsedAssemblyName parsedAssemblyName)
at nCrunch.Common.CustomAssemblyResolver.AssemblyResolve(Object sender, ResolveEventArgs args)
at System.AppDomain.OnAssemblyResolveEvent(RuntimeAssembly assembly, String assemblyFullName)


at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
at System.Reflection.RuntimeMethodInfo.FetchNonReturnParameters()
at System.Reflection.RuntimeMethodInfo.GetParameters()
at nCrunch.TestExecution.Reflection.Clr.ClrMethod.get_ParameterTypes()
at nCrunch.TestExecution.Reflection.ReflectedMethod.GetMemberIdentifier()
at nCrunch.TestExecution.Reflection.ReflectedType.()
at nCrunch.TestExecution.Reflection.ReflectedType.get_MethodsWithInheritance()
at nCrunch.Module.MSTest.Integration.MSTestDynamicDiscoverer.<>c__DisplayClass5_0.<FindFrameworkTestsInAssembly>b__1()
at nCrunch.Common.PerformanceTracking.PerfTracker.TrackActivity(String name, Action activity)
at nCrunch.Common.PerformanceTracking.PerfTracker.TryTrackActivity(String name, Action activity)
at nCrunch.Module.MSTest.Integration.MSTestDynamicDiscoverer.FindFrameworkTestsInAssembly(ReflectedAssembly assembly, FilePath assemblyFilePath, IList`1 referencedAssemblyFilePaths, ComponentUniqueName testComponentUniqueName, PlatformType platformType, DynamicProxy[] dynamicProxies)
at nCrunch.TestExecution.TestFinder..()
at nCrunch.Common.PerformanceTracking.PerfTracker.TrackActivity(String name, Action activity)
at nCrunch.TestExecution.TestFinder..()
at nCrunch.Common.PerformanceTracking.PerfTracker.TrackActivity(String name, Action activity)
at nCrunch.TestExecution.TestFinder.FindTestsForFrameworks(ReflectedAssembly assembly, FilePath assemblyFilePath, IList`1 referencedAssemblyFilePaths, DescribedTestFrameworkDiscoverer[] describedDiscoverers, ComponentUniqueName testComponentUniqueName, PlatformType platformType, DynamicProxy[] dynamicProxies)
at nCrunch.TestExecution.RemoteTaskRunner.AnalyseAssembly(DescribedTestFrameworkDiscoverer[] applicableFrameworks, ComponentUniqueName testComponentUniqueName, PerfTracker perfTracker, TaskLogId taskLogId)

I tried enabling 'Copy referenced assemblies to workspace'. But I get the same error.

The nuget package I use that provides the native libraries is structured a lot like this one: https://www.nuget.org/packages/Stub.System.Data.SQLite.Core.NetFramework/ At build, this will add a x86 and x64 subfolders in bin output and they will contain their respective platform specific assemblies. You can see the copy magic in the .targets file.

What can I do for such scenario?

Thanks,

Alex
Hi Alex,

My apologies. I hadn't realised this was failing on the analysis step. The best option here would be to make sure that your build system copies the correct x86/x64 matching file directly into the bin\debug directory (not in a x86/x64 subdir) so that it is collocated with the build output file. I would recommend doing this as a custom post-build step. You could make it conditional for NCrunch using a build condition so that it doesn't interfere with your normal operation. As long as the file exists in the same directory as the resolving assembly, the runtime should find it without custom search logic being necessary.
Hi Remco,

No need to apologize, this was my mistake. I will try the approach you suggest with a build condition.

Thanks for your help and the awesome product.

Alex

Post a reply

Log in to reply.