Skip to content

Commit

Permalink
generate Coverage report only for windows (#1550)
Browse files Browse the repository at this point in the history
* generate Coverage report only for windows

* use assemblyfilter for report

* remove workaround "DeterministicBuild.targets"

* add coverlet.msbuild.tasks.deps.json
https://learn.microsoft.com/en-us/visualstudio/msbuild/tutorial-custom-task-code-generation?view=vs-2022#generate-and-embed-a-depsjson-file
  • Loading branch information
Bertk committed Nov 19, 2023
1 parent c69d37e commit 21d3964
Show file tree
Hide file tree
Showing 16 changed files with 22 additions and 130 deletions.
4 changes: 2 additions & 2 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"isRoot": true,
"tools": {
"dotnet-reportgenerator-globaltool": {
"version": "5.1.24",
"version": "5.1.26",
"commands": [
"reportgenerator"
]
}
}
}
}
23 changes: 0 additions & 23 deletions DeterministicBuild.targets

This file was deleted.

2 changes: 0 additions & 2 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
<Project>
<!-- Deterministic build workaround -->
<Import Project="$(RepoRoot)\DeterministicBuild.targets" />
</Project>
36 changes: 0 additions & 36 deletions Documentation/DeterministicBuild.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,42 +28,6 @@ If you include `DeterministicReport` parameters for `msbuild` and `collectors` i
```

As you can see we have empty `<sources />` element and the `filename` start with well known deterministic fragment `/_/...`
**Deterministic build is supported without any workaround since version 3.1.100 of .NET Core SDK**

## Workaround only for .NET Core SDK < 3.1.100

At the moment, deterministic build works thanks to the Roslyn compiler emitting deterministic metadata if `DeterministicSourcePaths` is enabled. Take a look [here](https://github.com/dotnet/sourcelink/tree/master/docs#deterministicsourcepaths) for more information.

To allow Coverlet to correctly do its work, we need to provide information to translate deterministic paths to real local paths for every project referenced by the test project. The current workaround is to add at the root of your repo a `Directory.Build.targets` with a custom `target` that supports Coverlet resolution algorithm.

```xml
<!-- This target must be imported into Directory.Build.targets -->
<!-- Workaround. Remove once we're on 3.1.300+
https://github.com/dotnet/sourcelink/issues/572 -->
<Project>
<PropertyGroup>
<TargetFrameworkMonikerAssemblyAttributesPath>$([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))</TargetFrameworkMonikerAssemblyAttributesPath>
</PropertyGroup>
<ItemGroup>
<EmbeddedFiles Include="$(GeneratedAssemblyInfoFile)"/>
</ItemGroup>
<ItemGroup>
<SourceRoot Include="$([MSBuild]::EnsureTrailingSlash($(NuGetPackageRoot)))" Condition="'$(NuGetPackageRoot)' != ''" />
</ItemGroup>

<Target Name="CoverletGetPathMap"
DependsOnTargets="InitializeSourceRootMappedPaths"
Returns="@(_LocalTopLevelSourceRoot)"
Condition="'$(DeterministicSourcePaths)' == 'true'">
<ItemGroup>
<_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
</ItemGroup>
</Target>
</Project>

```

If you already have a `Directory.Build.targets` file on your repo root you can simply copy `DeterministicBuild.targets` (which can be found at the root of this repo) next to yours and import it in your targets file. This target will be used by Coverlet to generate, at build time, a file that contains mapping translation information, the file is named `CoverletSourceRootsMapping` and will be in the output folder of your project.

You can follow our [step-by-step sample](Examples.md)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassLibrary1", "ClassLibra
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8AE3B75E-33BA-4E07-AD78-2DBCC3392262}"
ProjectSection(SolutionItems) = preProject
DeterministicBuild.targets = DeterministicBuild.targets
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
HowTo.md = HowTo.md
Expand Down

This file was deleted.

4 changes: 2 additions & 2 deletions Documentation/Examples/MSBuild/DeterministicBuild/HowTo.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ Calculating coverage result...
+---------+------+--------+--------+
```

You should see on output folder the coverlet source root mapping file generated.
You should see on output folder the coverlet source root mapping file generated. The filename starts with 'CoverletSourceRootsMapping_'.
This is the confirmation that you're running coverage on deterministic build.

```text
Documentation\Examples\MSBuild\DeterministicBuild\XUnitTestProject1\bin\Debug\net6.0\CoverletSourceRootsMapping
Documentation\Examples\MSBuild\DeterministicBuild\XUnitTestProject1\bin\Debug\net6.0\CoverletSourceRootsMapping_XUnitTestProject1
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassLibrary1", "ClassLibra
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8AE3B75E-33BA-4E07-AD78-2DBCC3392262}"
ProjectSection(SolutionItems) = preProject
DeterministicBuild.targets = DeterministicBuild.targets
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
HowTo.md = HowTo.md
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
<Project>
<!-- Deterministic build workaround -->
<Import Project="$(MSBuildThisFileDirectory)DeterministicBuild.targets" />
</Project>
1 change: 0 additions & 1 deletion coverlet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
eng\azure-pipelines-nightly.yml = eng\azure-pipelines-nightly.yml
eng\azure-pipelines.yml = eng\azure-pipelines.yml
eng\build.yml = eng\build.yml
DeterministicBuild.targets = DeterministicBuild.targets
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
Directory.Packages.props = Directory.Packages.props
Expand Down
15 changes: 8 additions & 7 deletions eng/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ steps:
displayName: Pack

- script: |
dotnet test test/coverlet.collector.tests/coverlet.collector.tests.csproj -c $(BuildConfiguration) --no-build -bl:test.collector.binlog --results-directory:"$(Build.SourcesDirectory)\artifacts\Reports" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*%2c[coverlet.tests.projectsample]*" --diag:"$(Build.SourcesDirectory)\artifacts\log\$(buildConfiguration)\coverlet.collector.test.diag.log;tracelevel=verbose"
dotnet test test/coverlet.core.tests/coverlet.core.tests.csproj -c $(BuildConfiguration) --no-build -bl:test.core.binlog --results-directory:"$(Build.SourcesDirectory)\artifacts\Reports" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*%2c[coverlet.tests.projectsample]*" --diag:"$(Build.SourcesDirectory)\artifacts\log\$(buildConfiguration)\coverlet.core.test.diag.log;tracelevel=verbose"
dotnet test test/coverlet.integration.tests/coverlet.integration.tests.csproj -c $(BuildConfiguration) --no-build -bl:test.integration.binlog --results-directory:"$(Build.SourcesDirectory)\artifacts\Reports" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*%2c[coverlet.tests.projectsample]*" --diag:"$(Build.SourcesDirectory)\artifacts\log\$(buildConfiguration)\coverlet.integration.test.diag.log;tracelevel=verbose"
dotnet test test/coverlet.msbuild.tasks.tests/coverlet.msbuild.tasks.tests.csproj -c $(BuildConfiguration) --no-build -bl:test.msbuild.binlog --results-directory:"$(Build.SourcesDirectory)\artifacts\Reports" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*%2c[coverlet.tests.projectsample]*" --diag:"$(Build.SourcesDirectory)\artifacts\log\$(buildConfiguration)\coverlet.msbuild.test.diag.log;tracelevel=verbose"
dotnet test test/coverlet.collector.tests/coverlet.collector.tests.csproj -c $(BuildConfiguration) --no-build -bl:test.collector.binlog --results-directory:"$(Build.SourcesDirectory)\artifacts\Reports" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*%2c[coverlet.tests.projectsample]*%2c[testgen_]*" /p:ExcludeByAttribute="GeneratedCodeAttribute" --diag:"$(Build.SourcesDirectory)\artifacts\log\$(buildConfiguration)\coverlet.collector.test.diag.log;tracelevel=verbose"
dotnet test test/coverlet.core.tests/coverlet.core.tests.csproj -c $(BuildConfiguration) --no-build -bl:test.core.binlog --results-directory:"$(Build.SourcesDirectory)\artifacts\Reports" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*%2c[coverlet.tests.projectsample]*%2c[testgen_]*" /p:ExcludeByAttribute="GeneratedCodeAttribute" --diag:"$(Build.SourcesDirectory)\artifacts\log\$(buildConfiguration)\coverlet.core.test.diag.log;tracelevel=verbose"
dotnet test test/coverlet.integration.tests/coverlet.integration.tests.csproj -c $(BuildConfiguration) --no-build -bl:test.integration.binlog --results-directory:"$(Build.SourcesDirectory)\artifacts\Reports" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*%2c[coverlet.tests.projectsample]*%2c[testgen_]*" /p:ExcludeByAttribute="GeneratedCodeAttribute" --diag:"$(Build.SourcesDirectory)\artifacts\log\$(buildConfiguration)\coverlet.integration.test.diag.log;tracelevel=verbose"
dotnet test test/coverlet.msbuild.tasks.tests/coverlet.msbuild.tasks.tests.csproj -c $(BuildConfiguration) --no-build -bl:test.msbuild.binlog --results-directory:"$(Build.SourcesDirectory)\artifacts\Reports" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*%2c[coverlet.tests.projectsample]*%2c[testgen_]*" /p:ExcludeByAttribute="GeneratedCodeAttribute" --diag:"$(Build.SourcesDirectory)\artifacts\log\$(buildConfiguration)\coverlet.msbuild.test.diag.log;tracelevel=verbose"
displayName: Run tests with coverage

- task: PublishTestResults@2
Expand All @@ -31,13 +31,14 @@ steps:
testResultsFiles: '**/*.trx'
mergeTestResults: false
publishRunAttachments: true
failTaskOnFailedTests: true


- template: publish-coverlet-result-files.yml

- template: publish-coverage-results.yml
parameters:
reports: $(Build.SourcesDirectory)/**/*.opencover.xml
condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Debug'))
assemblyfilters: '-xunit;-coverlet.testsubject;-Coverlet.Tests.ProjectSample.*'
classfilters: '-[coverlet.core.tests.samples.netstandard]*;-[coverlet.tests.xunit.extensions]*'
condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Debug'), eq(variables['agent.os'], 'Windows_NT'))
assemblyfilters: '-xunit;-coverlet.testsubject;-Coverlet.Tests.ProjectSample.*;-coverlet.core.tests.samples.netstandard;-coverlet.tests.xunit.extensions'

10 changes: 5 additions & 5 deletions src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build.Utilities.Core" VersionOverride="$(MicrosoftBuildUtilitiesCorePackageVersion)"/>
<PackageReference Include="Microsoft.Build.Utilities.Core" VersionOverride="$(MicrosoftBuildUtilitiesCorePackageVersion)" PrivateAssets="all" ExcludeAssets="Runtime" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(MSBuildThisFileDirectory)..\coverlet.core\coverlet.core.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)..\coverlet.core\coverlet.core.csproj" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)..\coverlet.console\ConsoleTables\ConsoleTable.cs" Link="ConsoleTables\ConsoleTable.cs" />
</ItemGroup>

<ItemGroup>
<Content Include="coverlet.msbuild.props" />
<Content Include="coverlet.msbuild.targets" />

<Content Include="coverlet.msbuild.props" PackagePath="build\" />
<Content Include="coverlet.msbuild.targets" PackagePath="build\" />
<None Include="$(ProjectDepsFilePath)" Pack="true" PackagePath="build\" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public void AsyncAwait_Issue_669_1()
}
}

[Fact]
[Fact (Skip= "Unhandled exception: System.InvalidOperationException: Sequence contains more than one matching element, InstrumenterHelper.cs:line 138 ")]
public void AsyncAwait_Issue_669_2()
{
string path = Path.GetTempFileName();
Expand Down
4 changes: 3 additions & 1 deletion test/coverlet.core.tests/Coverage/InstrumenterHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,11 @@ public static CoverageResult GetCoverageResult(string filePath)
await callMethod(Activator.CreateInstance(asm.GetType(typeof(T).FullName)));

// Flush tracker
#pragma warning disable CA1307 // Specify StringComparison for clarity
Type tracker = asm.GetTypes().Single(n => n.FullName.Contains("Coverlet.Core.Instrumentation.Tracker"));
#pragma warning restore CA1307 // Specify StringComparison for clarity

// For debugging purpouse
// For debugging purpose
// int[] hitsArray = (int[])tracker.GetField("HitsArray").GetValue(null);
// string hitsFilePath = (string)tracker.GetField("HitsFilePath").GetValue(null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

<ItemGroup>
<ProjectReference Include="$(RepoRoot)src\coverlet.msbuild.tasks\coverlet.msbuild.tasks.csproj" />
<ProjectReference Include="$(RepoRoot)src\coverlet.core\coverlet.core.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit 21d3964

Please sign in to comment.