Support .NET Framework(>= net461) for in-process data collectors (#970)

Support .NET Framework(>= net461) for in-process data collectors
This commit is contained in:
Marco Rossignoli
2020-10-14 15:37:48 +02:00
committed by GitHub
parent c81b2b1bce
commit b43a320ffc
5 changed files with 53 additions and 9 deletions
+6 -1
View File
@@ -244,4 +244,9 @@ You can live attach and debug collectors with `COVERLET_DATACOLLECTOR_OUTOFPROC_
set COVERLET_DATACOLLECTOR_OUTOFPROC_DEBUG=1
set COVERLET_DATACOLLECTOR_INPROC_DEBUG=1
```
You will be asked to attach a debugger through UI popup.
You will be asked to attach a debugger through UI popup.
To enable exceptions log for in-process data collectors
```
set COVERLET_DATACOLLECTOR_INPROC_EXCEPTIONLOG_ENABLED=1
```
+9 -1
View File
@@ -1,6 +1,14 @@
# Coverlet integration with VSTest (a.k.a. Visual Studio Test Platform)
**At the moment collectors integration supports only .NET Core applications and not .NET Framework ones.**
**Supported runtime versions:**
Before version `3.0.0`
- .NET Core >= 2.0
- .NET Framework not fully supported(only out of process collector, could suffer of [known issue](https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/KnownIssues.md#1-vstest-stops-process-execution-earlydotnet-test))
Since version `3.0.0`
- .NET Core >= 2.0
- .NET Framework >= 4.6.1
As explained in quick start section to use collectors you need to run *SDK v2.2.401* or newer and your project file must reference `coverlet.collector.dll` and a minimum version of `Microsoft.NET.Test.Sdk`.
A sample project file looks like:
@@ -237,7 +237,7 @@ namespace Coverlet.Collector.DataCollection
/// <returns>An array of the values in the element</returns>
private string[] SplitElement(XmlElement element)
{
return element?.InnerText?.Split(',', StringSplitOptions.RemoveEmptyEntries).Where(value => !string.IsNullOrWhiteSpace(value)).Select(value => value.Trim()).ToArray();
return element?.InnerText?.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Where(value => !string.IsNullOrWhiteSpace(value)).Select(value => value.Trim()).ToArray();
}
}
}
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using coverlet.collector.Resources;
using Coverlet.Collector.Utilities;
@@ -14,6 +15,7 @@ namespace Coverlet.Collector.DataCollection
public class CoverletInProcDataCollector : InProcDataCollection
{
private TestPlatformEqtTrace _eqtTrace;
private bool _enableExceptionLog = false;
private void AttachDebugger()
{
@@ -24,10 +26,18 @@ namespace Coverlet.Collector.DataCollection
}
}
private void EnableExceptionLog()
{
if (int.TryParse(Environment.GetEnvironmentVariable("COVERLET_DATACOLLECTOR_INPROC_EXCEPTIONLOG_ENABLED"), out int result) && result == 1)
{
_enableExceptionLog = true;
}
}
public void Initialize(IDataCollectionSink dataCollectionSink)
{
AttachDebugger();
EnableExceptionLog();
_eqtTrace = new TestPlatformEqtTrace();
_eqtTrace.Verbose("Initialize CoverletInProcDataCollector");
@@ -61,9 +71,12 @@ namespace Coverlet.Collector.DataCollection
}
catch (Exception ex)
{
_eqtTrace.Error("{0}: Failed to unload module with error: {1}", CoverletConstants.InProcDataCollectorName, ex);
string errorMessage = string.Format(Resources.FailedToUnloadModule, CoverletConstants.InProcDataCollectorName);
throw new CoverletDataCollectorException(errorMessage, ex);
if (_enableExceptionLog)
{
_eqtTrace.Error("{0}: Failed to unload module with error: {1}", CoverletConstants.InProcDataCollectorName, ex);
string errorMessage = string.Format(Resources.FailedToUnloadModule, CoverletConstants.InProcDataCollectorName);
throw new CoverletDataCollectorException(errorMessage, ex);
}
}
}
}
@@ -89,7 +102,25 @@ namespace Coverlet.Collector.DataCollection
}
catch (Exception ex)
{
_eqtTrace.Warning("{0}: Failed to get Instrumentation class with error: {1}", CoverletConstants.InProcDataCollectorName, ex);
if (_enableExceptionLog)
{
StringBuilder exceptionString = new StringBuilder();
exceptionString.AppendFormat("{0}: Failed to get Instrumentation class for assembly '{1}' with error: {2}",
CoverletConstants.InProcDataCollectorName, assembly, ex);
exceptionString.AppendLine();
if (ex is ReflectionTypeLoadException rtle)
{
exceptionString.AppendLine("ReflectionTypeLoadException list:");
foreach (Exception loaderEx in rtle.LoaderExceptions)
{
exceptionString.AppendLine(loaderEx.ToString());
}
}
_eqtTrace.Warning(exceptionString.ToString());
}
return null;
}
}
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyTitle>coverlet.collector</AssemblyTitle>
<DevelopmentDependency>true</DevelopmentDependency>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>