Support .NET Framework(>= net461) for in-process data collectors (#970)
Support .NET Framework(>= net461) for in-process data collectors
This commit is contained in:
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user