Skip to content

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

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Documentation/Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

10 changes: 9 additions & 1 deletion Documentation/VSTestIntegration.md
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ private string[] ParseDoesNotReturnAttributes(XmlElement configurationElement)
/// <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();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;

using coverlet.collector.Resources;
using Coverlet.Collector.Utilities;
Expand All @@ -14,6 +15,7 @@ namespace Coverlet.Collector.DataCollection
public class CoverletInProcDataCollector : InProcDataCollection
{
private TestPlatformEqtTrace _eqtTrace;
private bool _enableExceptionLog = false;

private void AttachDebugger()
{
Expand All @@ -24,10 +26,18 @@ private void AttachDebugger()
}
}

public void Initialize(IDataCollectionSink dataCollectionSink)
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");
Expand Down Expand Up @@ -61,9 +71,12 @@ public void TestSessionEnd(TestSessionEndArgs testSessionEndArgs)
}
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);
}
}
}
}
Expand All @@ -89,7 +102,25 @@ private Type GetInstrumentationClass(Assembly assembly)
}
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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/coverlet.collector/coverlet.collector.csproj
Original file line number Diff line number Diff line change
@@ -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>
Expand Down