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

[coverlet] Unable to instrument module for pdbs while launching tests in multiple threads #650

Closed
tempora-mutantur opened this issue Dec 9, 2019 · 10 comments · Fixed by #656
Labels
bug Something isn't working

Comments

@tempora-mutantur
Copy link

Hello.
We collect code coverage using coverlet.msbuild version 2.7.0. We do this on Windows Server VMs and we launch our NUnit tests for a *.sln file using the "dotnet test MySolution.sln ..." command. This launches tests in parallel for every test project, and as I expect, this leads to such warnings:

'[coverlet] Unable to instrument module: C:\Repositories\myproject.git\Tests\Output\UnitTests\TerrificMethods\Core.dll' because : The process cannot access the file 'C:\Repositories\myproject.git\src\Core\obj\debug\Core.pdb' because it is being used by another process.

Because of this code coverage can change from one tests launch to another.
Thank you.

@MarcoRossignoli
Copy link
Collaborator

Is it a warning or an error?can you copy/paste full line?
Can you provide a small repro?

@MarcoRossignoli MarcoRossignoli added the needs more info More details are needed label Dec 9, 2019
@tempora-mutantur
Copy link
Author

It's a warning,

C:\Users\savanchuk.nuget\packages\coverlet.msbuild\2.7.0\build\coverlet.msbuild.targets(7,5): warning : [coverlet] Unable to instrument module: 'C:\Repositories\repo.git\Tests\Output\UnitTests\Server.UnitTests\Server.Views.dll' because : The process cannot access the file 'C:\Repositories\repo.git\src\Server\obj\Debug\netcoreapp2.1\Server.Views.pdb' because it is being used by another process. [C:\Repositories\repo.git\src\Server.UnitTests\Server.UnitTests.csproj]

Maybe I'm missing something, but it seems that it would just skip this PDB in this case.

https://github.com/tonerdo/coverlet/blob/57ec8d39a86af31defbd4ce6585f71775f9ae471/src/coverlet.core/Coverage.cs#L117

I think the repro would be a couple of test projects that use some common dll and launch tests for these projects in parallel.

I may prepare a little sample.

@MarcoRossignoli
Copy link
Collaborator

MarcoRossignoli commented Dec 9, 2019

Yep could be great a repro...because I did a check on codebase and we open pdbs always in read mode share read so it's strange...I'd like to understand who is locking that guy.

@MarcoRossignoli
Copy link
Collaborator

Could be...there are some place that could overlap, when we talk about concurrent access without a repro it's hard to find where is the issue...if you provide a repro I could understand how to fix it or what strategy take.

@MarcoRossignoli
Copy link
Collaborator

MarcoRossignoli commented Dec 9, 2019

FYI I've opened some issue on msbuild repo to understand how to tackle this kind of issue...but seem that there is no great way at the moment dotnet/msbuild#4898 dotnet/msbuild#4954

You could also try to pass -m:1 to command line...it slow down test but could work https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2019

@tempora-mutantur
Copy link
Author

Hello, @MarcoRossignoli .

I've created this repo that reproduces the problem:
https://github.com/tempora-mutantur/coverletbugsample

Launching the build.ps1 script will run dotnet test for the src\ClassLibrary\ClassLibrary.sln solution file.

And I see these warnings in output:

C:\Users\savanchuk.nuget\packages\coverlet.msbuild\2.7.0\build\coverlet.msbuild.targets(7,5): warning : [coverlet] Unable to instrument module: 'C:\Repositories\coverletsampleparallel\src\ClassLibrary\ClassLibrary.UnitTests3\bin\Debug\ClassLibrary.dll' because : The process cannot access the file 'C:\Repositories\coverletsampleparallel\src\ClassLibrary\ClassLibrary\obj\Debug\ClassLibrary.pdb' because it is being used by another process. [C:\Repositories\coverletsampleparallel\src\ClassLibrary\ClassLibrary.UnitTests3\ClassLibrary.UnitTests3.csproj]
C:\Users\savanchuk.nuget\packages\coverlet.msbuild\2.7.0\build\coverlet.msbuild.targets(7,5): warning : [coverlet] Unable to instrument module: 'C:\Repositories\coverletsampleparallel\src\ClassLibrary\ClassLibrary.UnitTests4\bin\Debug\ClassLibrary.dll' because : The process cannot access the file 'C:\Repositories\coverletsampleparallel\src\ClassLibrary\ClassLibrary\obj\Debug\ClassLibrary.pdb' because it is being used by another process. [C:\Repositories\coverletsampleparallel\src\ClassLibrary\ClassLibrary.UnitTests4\ClassLibrary.UnitTests4.csproj]

Code coverage result for this:
image

Changing
https://github.com/tempora-mutantur/coverletbugsample/blob/master/build.cake#L44
with -m:1 as you suggested:

Code coverage is collected correctly:
image

Thank you

@MarcoRossignoli
Copy link
Collaborator

I see thank you

@MarcoRossignoli MarcoRossignoli added bug Something isn't working and removed needs more info More details are needed labels Dec 10, 2019
@tkukushkin
Copy link

@MarcoRossignoli this issue is still reproducable on coverlet.console 1.7.0.0. We get such error:

---> System.IO.IOException: The process cannot access the file '/Users/tkukushkin/Projects/builders-balance/Scheduler/bin/Debug/netcoreapp3.1/Scheduler.pdb' because it is being used by another process.
   at System.IO.FileStream.Init(FileMode mode, FileShare share, String originalPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at System.IO.FileSystem.CopyFile(String sourceFullPath, String destFullPath, Boolean overwrite)
   at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)
   at Coverlet.Core.Helpers.FileSystem.Copy(String sourceFileName, String destFileName, Boolean overwrite) in /_/src/coverlet.core/Helpers/FileSystem.cs:line 33
   at Coverlet.Core.Helpers.InstrumentationHelper.<>c__DisplayClass12_0.<RestoreOriginalModules>b__0() in /_/src/coverlet.core/Helpers/InstrumentationHelper.cs:line 245
   at Coverlet.Core.Helpers.RetryHelper.<>c__DisplayClass0_0.<Retry>b__0() in /_/src/coverlet.core/Helpers/RetryHelper.cs:line 26
   at Coverlet.Core.Helpers.RetryHelper.Do[T](Func`1 action, Func`1 backoffStrategy, Int32 maxAttemptCount) in /_/src/coverlet.core/Helpers/RetryHelper.cs:line 52
   --- End of inner exception stack trace ---
   at Coverlet.Core.Helpers.RetryHelper.Do[T](Func`1 action, Func`1 backoffStrategy, Int32 maxAttemptCount) in /_/src/coverlet.core/Helpers/RetryHelper.cs:line 59
   at Coverlet.Core.Helpers.RetryHelper.Retry(Action action, Func`1 backoffStrategy, Int32 maxAttemptCount) in /_/src/coverlet.core/Helpers/RetryHelper.cs:line 28
   at Coverlet.Core.Helpers.InstrumentationHelper.RestoreOriginalModules() in /_/src/coverlet.core/Helpers/InstrumentationHelper.cs:line 242
   at Coverlet.Core.Helpers.InstrumentationHelper.<.ctor>b__5_0(Object s, EventArgs e) in /_/src/coverlet.core/Helpers/InstrumentationHelper.cs:line 26
   at System.AppContext.OnProcessExit()
 ---> (Inner Exception #1) System.IO.IOException: The process cannot access the file '/Users/tkukushkin/Projects/builders-balance/Scheduler/bin/Debug/netcoreapp3.1/Scheduler.pdb' because it is being used by another process.
   at System.IO.FileStream.Init(FileMode mode, FileShare share, String originalPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at System.IO.FileSystem.CopyFile(String sourceFullPath, String destFullPath, Boolean overwrite)
   at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)
   at Coverlet.Core.Helpers.FileSystem.Copy(String sourceFileName, String destFileName, Boolean overwrite) in /_/src/coverlet.core/Helpers/FileSystem.cs:line 33
   at Coverlet.Core.Helpers.InstrumentationHelper.<>c__DisplayClass12_0.<RestoreOriginalModules>b__0() in /_/src/coverlet.core/Helpers/InstrumentationHelper.cs:line 245
   at Coverlet.Core.Helpers.RetryHelper.<>c__DisplayClass0_0.<Retry>b__0() in /_/src/coverlet.core/Helpers/RetryHelper.cs:line 26
   at Coverlet.Core.Helpers.RetryHelper.Do[T](Func`1 action, Func`1 backoffStrategy, Int32 maxAttemptCount) in /_/src/coverlet.core/Helpers/RetryHelper.cs:line 52<---

@MarcoRossignoli
Copy link
Collaborator

@tkukushkin can you open another issue please this is very old, also can you take a look if you're some antivirus active and in case shutdown for testing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants