Skip to content

Commit

Permalink
Fixes CoverletSourceRootsMapping issue (#1456)
Browse files Browse the repository at this point in the history
  • Loading branch information
daveMueller authored Mar 21, 2023
1 parent 3bbe502 commit d936138
Show file tree
Hide file tree
Showing 18 changed files with 113 additions and 60 deletions.
1 change: 1 addition & 0 deletions Documentation/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased

### Fixed
-Could not write lines to file CoverletSourceRootsMapping - in use by another process [#1155](https://github.com/coverlet-coverage/coverlet/issues/1155)
-Incorrect coverage for methods returning IAsyncEnumerable in generic classes [#1383](https://github.com/coverlet-coverage/coverlet/issues/1383)
-Wrong branch coverage for async methods .NET Standard 1.x [#1376](https://github.com/coverlet-coverage/coverlet/issues/1376)
-Empty path exception in visual basic projects [#775](https://github.com/coverlet-coverage/coverlet/issues/775)
Expand Down
4 changes: 2 additions & 2 deletions Documentation/Examples/VSTest/DeterministicBuild/HowTo.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Add collectors package version generated to `"..\Documentation\Examples\VSTest\D
Go to test project folder and run
```
C:\git\coverlet\Documentation\Examples\VSTest\DeterministicBuild (detbuilddocs -> origin)
λ dotnet test --collect:"XPlat Code Coverage" /p:DeterministicSourcePaths=true
λ dotnet test --collect:"XPlat Code Coverage" /p:DeterministicSourcePaths=true -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.DeterministicReport=true
Test run for C:\git\coverlet\Documentation\Examples\VSTest\DeterministicBuild\XUnitTestProject1\bin\Debug\netcoreapp3.1\XUnitTestProject1.dll(.NETCoreApp,Version=v3.1)
Microsoft (R) Test Execution Command Line Tool Version 16.5.0
Copyright (c) Microsoft Corporation. All rights reserved.
Expand All @@ -78,5 +78,5 @@ Total tests: 1
You should see on output folder the coverlet source root mapping file generated.
This is the confirmation that you're running coverage on deterministic build.
```
Documentation\Examples\VSTest\DeterministicBuild\XUnitTestProject1\bin\Debug\netcoreapp3.1\CoverletSourceRootsMapping
Documentation\Examples\VSTest\DeterministicBuild\XUnitTestProject1\bin\Debug\netcoreapp3.1\CoverletSourceRootsMapping_XUnitTestProject1
```
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,13 @@ private static IServiceCollection GetDefaultServiceCollection(TestPlatformEqtTra
serviceCollection.AddTransient<IRetryHelper, RetryHelper>();
serviceCollection.AddTransient<IProcessExitHandler, ProcessExitHandler>();
serviceCollection.AddTransient<IFileSystem, FileSystem>();
serviceCollection.AddTransient<IAssemblyAdapter, AssemblyAdapter>();
serviceCollection.AddTransient<ILogger, CoverletLogger>(_ => new CoverletLogger(eqtTrace, logger));
// We need to keep singleton/static semantics
serviceCollection.AddSingleton<IInstrumentationHelper, InstrumentationHelper>();
// We cache resolutions
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService<ILogger>(), serviceProvider.GetRequiredService<IFileSystem>()));
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(serviceProvider =>
new SourceRootTranslator(testModule, serviceProvider.GetRequiredService<ILogger>(), serviceProvider.GetRequiredService<IFileSystem>(), serviceProvider.GetRequiredService<IAssemblyAdapter>()));
serviceCollection.AddSingleton<ICecilSymbolHelper, CecilSymbolHelper>();
return serviceCollection;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
<_mapping Include="@(_byProject->'%(Identity)|%(OriginalPath)=%(MappedPath)')" />
</ItemGroup>
<PropertyGroup>
<_sourceRootMappingFilePath>$([MSBuild]::EnsureTrailingSlash('$(OutputPath)'))CoverletSourceRootsMapping</_sourceRootMappingFilePath>
<_sourceRootMappingFilePath>$([MSBuild]::EnsureTrailingSlash('$(OutputPath)'))CoverletSourceRootsMapping_$(AssemblyName)</_sourceRootMappingFilePath>
</PropertyGroup>
<WriteLinesToFile File="$(_sourceRootMappingFilePath)" Lines="@(_mapping)"
Overwrite="true" Encoding="Unicode"
Expand Down
10 changes: 10 additions & 0 deletions src/coverlet.core/Abstractions/IAssemblyAdapter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) Toni Solarin-Sodara
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Coverlet.Core.Abstractions
{
internal interface IAssemblyAdapter
{
string GetAssemblyName(string assemblyPath);
}
}
16 changes: 16 additions & 0 deletions src/coverlet.core/Helpers/AssemblyAdapter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Toni Solarin-Sodara
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Reflection;
using Coverlet.Core.Abstractions;

namespace Coverlet.Core.Helpers
{
internal class AssemblyAdapter : IAssemblyAdapter
{
public string GetAssemblyName(string assemblyPath)
{
return AssemblyName.GetAssemblyName(assemblyPath).Name;
}
}
}
10 changes: 7 additions & 3 deletions src/coverlet.core/Helpers/SourceRootTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal class SourceRootTranslator : ISourceRootTranslator
private readonly IFileSystem _fileSystem;
private readonly Dictionary<string, List<SourceRootMapping>> _sourceRootMapping;
private readonly Dictionary<string, List<string>> _sourceToDeterministicPathMapping;
private const string MappingFileName = "CoverletSourceRootsMapping";
private readonly string _mappingFileName;
private Dictionary<string, string> _resolutionCacheFiles;

public SourceRootTranslator(ILogger logger, IFileSystem fileSystem)
Expand All @@ -32,7 +32,7 @@ public SourceRootTranslator(ILogger logger, IFileSystem fileSystem)
_sourceRootMapping = new Dictionary<string, List<SourceRootMapping>>();
}

public SourceRootTranslator(string moduleTestPath, ILogger logger, IFileSystem fileSystem)
public SourceRootTranslator(string moduleTestPath, ILogger logger, IFileSystem fileSystem, IAssemblyAdapter assemblyAdapter)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
Expand All @@ -44,6 +44,10 @@ public SourceRootTranslator(string moduleTestPath, ILogger logger, IFileSystem f
{
throw new FileNotFoundException($"Module test path '{moduleTestPath}' not found", moduleTestPath);
}

string assemblyName = assemblyAdapter.GetAssemblyName(moduleTestPath);
_mappingFileName = $"CoverletSourceRootsMapping_{assemblyName}";

_sourceRootMapping = LoadSourceRootMapping(Path.GetDirectoryName(moduleTestPath));
_sourceToDeterministicPathMapping = LoadSourceToDeterministicPathMapping(_sourceRootMapping);
}
Expand Down Expand Up @@ -75,7 +79,7 @@ private Dictionary<string, List<SourceRootMapping>> LoadSourceRootMapping(string
{
var mapping = new Dictionary<string, List<SourceRootMapping>>();

string mappingFilePath = Path.Combine(directory, MappingFileName);
string mappingFilePath = Path.Combine(directory, _mappingFileName);
if (!_fileSystem.Exists(mappingFilePath))
{
return mapping;
Expand Down
4 changes: 3 additions & 1 deletion src/coverlet.msbuild.tasks/InstrumentationTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ public override bool Execute()
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<IProcessExitHandler, ProcessExitHandler>();
serviceCollection.AddTransient<IFileSystem, FileSystem>();
serviceCollection.AddTransient<IAssemblyAdapter, AssemblyAdapter>();
serviceCollection.AddTransient<IConsole, SystemConsole>();
serviceCollection.AddTransient<ILogger, MSBuildLogger>(_ => _logger);
serviceCollection.AddTransient<IRetryHelper, RetryHelper>();
// We cache resolutions
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(serviceProvider => new SourceRootTranslator(Path, serviceProvider.GetRequiredService<ILogger>(), serviceProvider.GetRequiredService<IFileSystem>()));
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(serviceProvider =>
new SourceRootTranslator(Path, serviceProvider.GetRequiredService<ILogger>(), serviceProvider.GetRequiredService<IFileSystem>(), serviceProvider.GetRequiredService<IAssemblyAdapter>()));
// We need to keep singleton/static semantics
serviceCollection.AddSingleton<IInstrumentationHelper, InstrumentationHelper>();
serviceCollection.AddSingleton<ICecilSymbolHelper, CecilSymbolHelper>();
Expand Down
2 changes: 1 addition & 1 deletion src/coverlet.msbuild.tasks/coverlet.msbuild.targets
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<_mapping Include="@(_byProject->'%(Identity)|%(OriginalPath)=%(MappedPath)')" />
</ItemGroup>
<PropertyGroup>
<_sourceRootMappingFilePath>$([MSBuild]::EnsureTrailingSlash('$(OutputPath)'))CoverletSourceRootsMapping</_sourceRootMappingFilePath>
<_sourceRootMappingFilePath>$([MSBuild]::EnsureTrailingSlash('$(OutputPath)'))CoverletSourceRootsMapping_$(AssemblyName)</_sourceRootMappingFilePath>
</PropertyGroup>
<WriteLinesToFile File="$(_sourceRootMappingFilePath)" Lines="@(_mapping)"
Overwrite="true" Encoding="Unicode"
Expand Down
Loading

0 comments on commit d936138

Please sign in to comment.