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 instrument module - due to Microsoft.Extensions.DependencyInjection.Abstractions #1102

Open
dea82 opened this issue Mar 1, 2021 · 8 comments
Labels
stale waiting for customer Waiting for customer action

Comments

@dea82
Copy link

dea82 commented Mar 1, 2021

I try to run coverage with a .Net 5 NUnint test project using Coverlet collector 3.0.3. The project is not producing coverage project under test but for referenced class libraries there are coverage.

I'm running the following command:
dotnet test <MY_TEST_PROJECT> --collect:"XPlat Code Coverage" --diag:log.txt

When examining the data collector log it seems to be related to Microsoft.Extensions.DependencyInjection.Abstractions is missing:

TpTrace Verbose: 0 : 36966, 1, 2021/03/01, 22:24:13.727, 4049879208140, datacollector.dll, [coverlet]TryWithCustomResolverOnDotNetCore exception: System.InvalidOperationException: Cannot find reference assembly 'WindowsBase.dll' file for package WindowsBase
   at Microsoft.Extensions.DependencyModel.Resolution.ReferenceAssemblyPathResolver.TryResolveAssemblyPaths(CompilationLibrary library, List`1 assemblies)
   at Microsoft.Extensions.DependencyModel.Resolution.CompositeCompilationAssemblyResolver.TryResolveAssemblyPaths(CompilationLibrary library, List`1 assemblies)
   at Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths(ICompilationAssemblyResolver[] customResolvers)
   at Coverlet.Core.Instrumentation.NetstandardAwareAssemblyResolver.TryWithCustomResolverOnDotNetCore(AssemblyNameReference name) in /_/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs:line 157
TpTrace Warning: 0 : 36966, 1, 2021/03/01, 22:24:13.728, 4049879564668, datacollector.dll, [coverlet]Unable to instrument module: /Users/sensitive_path/sensitive.dll because : AssemblyResolutionException for 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Try to add <PreserveCompilationContext>true</PreserveCompilationContext> to test projects </PropertyGroup> or pass '/p:CopyLocalLockFileAssemblies=true' option to the 'dotnet test' command-line

(A lot more of the first kind of log Cannot find reference assembly 'X.dll' file for package Y.)

I've tried to add <PreserveCompilationContext>true</PreserveCompilationContext> but it didn't help.

The only thing helping has been to manually copy the file Microsoft.Extensions.DependencyInjection.Abstractions.dll to the same path as test dll /Users/sensitive_path/bin/Debug/net5.0/. That generates coverage for project under test as well.

Any advise what I'm doing wrong? I can provide more logs if necessary (just have to wash out some sensitive data)

@daveMueller daveMueller added the untriaged To be investigated label Mar 1, 2021
@daveMueller
Copy link
Collaborator

Looks to me like this known issue. Could you try a dotnet publish before because then all references are resolved to the output directory.

@MarcoRossignoli
Copy link
Collaborator

MarcoRossignoli commented Mar 2, 2021

The only thing helping has been to manually copy the file Microsoft.Extensions.DependencyInjection.Abstractions.dll

Also as another workaround(if publish doesn't work) you could add direct reference of that lib(same version) to test project.

@MarcoRossignoli MarcoRossignoli added waiting for customer Waiting for customer action and removed untriaged To be investigated labels Mar 2, 2021
@dea82
Copy link
Author

dea82 commented Mar 2, 2021

Running dotnet <MY_TEST_PROJECT> --collect:"XPlat Code Coverage" --diag:log.txt will output to:
<MY_TEST_PROJECT>/bin/Debug/net5.0/Myapp.dll

However publish puts it's output in:
<MY_TEST_PROJECT>/bin/Debug/net5.0/publish/Myapp.dll

But publishing to the same folder, with -o, as build it works. Not really convenient in a CI-pipeline but works...

@MarcoRossignoli: Unfortunately it didn't work by reference Microsoft.Extensions.DependencyInjection.Abstractions direct in test project. The Microsoft.Extensions.DependencyInjection.Abstractions.dll is not copied to output directory even if it's referenced(!).

@LeVraiSylvain
Copy link

Same issue here

Workaround 1 : Publishing to the test project output folder
Workaround 2 : Adding Microsoft.Extensions.DependencyInjection.Abstractions.dll to the root of the test project. (Don't need to copy the file to the output folder)

image

@d1820
Copy link

d1820 commented Jan 4, 2022

Update: We fixed this by placing the <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" /> to the test project not instrumenting property. Even though we are still running the actually code at 5.0.0 it resolved the issue

@brenwebber
Copy link

I am having the same issue in both .net 5 and .net 6. I tried a bunch of steps to debug this further.

If I copied the Microsoft.Extensions.DependencyInjection.Abstractions.dll (v6.0.0) from the Release\net6.0\refs folder to the Release\net6.0 folder I would then get this error when running the tests (not from the diagnostic logs):

Data collection : Data collector 'XPlat code coverage' threw an exception during type loading, construction, or initialization: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (0x80131621) File name: 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.IO.FileLoadException: Assembly with same name is already loaded ...

What is interesting about this is that it is complaining about version 2.2.0.0 which is not referenced directly anywhere in my projects.

In the end, after trying all the suggestions above, the only thing that eventually worked was the 2nd Workaround suggested by @LeVraiSylvain of copying this assembly into the root folder of the test project. Not too happy with this hack but things must go on.

@BlackGad
Copy link
Contributor

To make this work you need proper *.deps.json file with additional compile elements which can be omitted in generic build but present when you publish your project/solution.

In depth - Microsoft.Extensions.DependencyInjection.Abstractions assembly on generic build become conflicted between:
CopyLocal

ItemName=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
  ConflictItemType=CopyLocal
  NuGetPackageId=Microsoft.Extensions.DependencyInjection.Abstractions
  FullPath=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
  RootDir=C:\
  Filename=Microsoft.Extensions.DependencyInjection.Abstractions
  Extension=.dll
  RelativeDir=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\
  Directory=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\
  RecursiveDir=
  Identity=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
  ModifiedTime=2021-10-23 02:48:34.0000000
  CreatedTime=2022-05-31 18:05:37.7765097
  AccessedTime=2023-03-15 10:39:06.6255910
  DefiningProjectFullPath=C:\Program Files\dotnet\sdk\7.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.ConflictResolution.targets
  DefiningProjectDirectory=C:\Program Files\dotnet\sdk\7.0.101\Sdks\Microsoft.NET.Sdk\targets\
  DefiningProjectName=Microsoft.NET.ConflictResolution
  DefiningProjectExtension=.targets

and Reference

ItemName=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
  ConflictItemType=Reference
  NuGetPackageId=Microsoft.Extensions.DependencyInjection.Abstractions
  FullPath=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
  RootDir=C:\
  Filename=Microsoft.Extensions.DependencyInjection.Abstractions
  Extension=.dll
  RelativeDir=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\
  Directory=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\
  RecursiveDir=
  Identity=<userFolder>\.nuget\packages\microsoft.extensions.dependencyinjection.abstractions\6.0.0\lib\net6.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
  ModifiedTime=2021-10-23 02:48:34.0000000
  CreatedTime=2022-05-31 18:05:37.7765097
  AccessedTime=2023-03-15 10:39:06.6255910
  DefiningProjectFullPath=C:\Program Files\dotnet\sdk\7.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.ConflictResolution.targets
  DefiningProjectDirectory=C:\Program Files\dotnet\sdk\7.0.101\Sdks\Microsoft.NET.Sdk\targets\
  DefiningProjectName=Microsoft.NET.ConflictResolution
  DefiningProjectExtension=.targets

So on GenerateBuildDependencyFile msuild target they will be just skipped

<ItemGroup>
      <ResolvedCompileFileDefinitions Remove="@(_ConflictPackageFiles)" Condition="'%(_ConflictPackageFiles.ConflictItemType)' == 'Reference'" />
      <NativeCopyLocalItems Remove="@(_ConflictPackageFiles)" Condition="'%(_ConflictPackageFiles.ConflictItemType)' != 'Reference'" />
      <ResourceCopyLocalItems Remove="@(_ConflictPackageFiles)" Condition="'%(_ConflictPackageFiles.ConflictItemType)' != 'Reference'" />
      <RuntimeCopyLocalItems Remove="@(_ConflictPackageFiles)" Condition="'%(_ConflictPackageFiles.ConflictItemType)' != 'Reference'" />
      <RuntimeTargetsCopyLocalItems Remove="@(_ConflictPackageFiles)" Condition="'%(_ConflictPackageFiles.ConflictItemType)' != 'Reference'" />
      <RuntimePackAsset Remove="@(_ConflictPackageFiles)" Condition="'%(_ConflictPackageFiles.ConflictItemType)' != 'Reference'" />
    </ItemGroup>

    <GenerateDepsFile ProjectPath="$(MSBuildProjectFullPath)"
                      AssetsFilePath="$(ProjectAssetsFile)"
                      DepsFilePath="$(ProjectDepsFilePath)"
                      TargetFramework="$(TargetFramework)"
                      AssemblyName="$(AssemblyName)"
                      AssemblyExtension="$(TargetExt)"
                      AssemblyVersion="$(Version)"
                      AssemblySatelliteAssemblies="@(IntermediateSatelliteAssembliesWithTargetPath)"
                      ReferencePaths="@(ReferencePath)"
                      ReferenceDependencyPaths="@(ReferenceDependencyPaths)"
                      ReferenceSatellitePaths="@(ReferenceSatellitePaths)"
                      ReferenceAssemblies="@(_ReferenceAssemblies)"
                      RuntimePackAssets="@(RuntimePackAsset)"
                      IncludeMainProject="$(IncludeMainProjectInDepsFile)"
                      RuntimeIdentifier="$(RuntimeIdentifier)"
                      PlatformLibraryName="$(MicrosoftNETPlatformLibrary)"
                      RuntimeFrameworks="@(RuntimeFramework)"
                      CompilerOptions="@(DependencyFileCompilerOptions)"
                      CompileReferences="@(ResolvedCompileFileDefinitions)"
                      ResolvedNuGetFiles="@(NativeCopyLocalItems);@(ResourceCopyLocalItems);@(RuntimeCopyLocalItems)"
                      UserRuntimeAssemblies="@(UserRuntimeAssembly)"
                      ResolvedRuntimeTargetsFiles="@(RuntimeTargetsCopyLocalItems)"
                      IsSelfContained="$(SelfContained)"
                      IncludeRuntimeFileVersions="$(IncludeFileVersionsInDependencyFile)"
                      RuntimeGraphPath="$(BundledRuntimeIdentifierGraphFile)"/>

When you publish your output folder there are no Copy local assemblies so there are no conflict and *.deps.json contains all this missed assemblies.

@github-actions
Copy link

This issue is stale because it has been open for 3 months with no activity.

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

No branches or pull requests

7 participants