From 641dba9fb09626dac012e1a326a074d7c8eed393 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 30 Jan 2019 08:08:26 -0600 Subject: [PATCH] Implement a VSTest data collector to write coverage data to disk Fixes #210 --- coverlet.sln | 15 ++++ .../CoverletDataCollector.cs | 73 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 1 + .../coverlet.datacollector.csproj | 28 +++++++ .../coverlet.datacollector.snk | Bin 0 -> 596 bytes 5 files changed, 117 insertions(+) create mode 100644 src/coverlet.datacollector/CoverletDataCollector.cs create mode 100644 src/coverlet.datacollector/Properties/AssemblyInfo.cs create mode 100644 src/coverlet.datacollector/coverlet.datacollector.csproj create mode 100644 src/coverlet.datacollector/coverlet.datacollector.snk diff --git a/coverlet.sln b/coverlet.sln index 6f42d08b2..128bfb62a 100644 --- a/coverlet.sln +++ b/coverlet.sln @@ -21,6 +21,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "coverlet.core.performancete EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "coverlet.template", "src\coverlet.template\coverlet.template.csproj", "{FF16BD00-4BE7-41F3-95AE-F69B56E5E254}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "coverlet.datacollector", "src\coverlet.datacollector\coverlet.datacollector.csproj", "{A207B2FD-9533-4F89-BCB9-86512E8743CB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -115,6 +117,18 @@ Global {FF16BD00-4BE7-41F3-95AE-F69B56E5E254}.Release|x64.Build.0 = Release|Any CPU {FF16BD00-4BE7-41F3-95AE-F69B56E5E254}.Release|x86.ActiveCfg = Release|Any CPU {FF16BD00-4BE7-41F3-95AE-F69B56E5E254}.Release|x86.Build.0 = Release|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Debug|x64.ActiveCfg = Debug|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Debug|x64.Build.0 = Debug|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Debug|x86.ActiveCfg = Debug|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Debug|x86.Build.0 = Debug|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Release|Any CPU.Build.0 = Release|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Release|x64.ActiveCfg = Release|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Release|x64.Build.0 = Release|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Release|x86.ActiveCfg = Release|Any CPU + {A207B2FD-9533-4F89-BCB9-86512E8743CB}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -127,6 +141,7 @@ Global {AE117FAA-C21D-4F23-917E-0C8050614750} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} {C68CF6DE-F86C-4BCF-BAB9-7A60C320E1F9} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} {FF16BD00-4BE7-41F3-95AE-F69B56E5E254} = {E877EBA4-E78B-4F7D-A2D3-1E070FED04CD} + {A207B2FD-9533-4F89-BCB9-86512E8743CB} = {E877EBA4-E78B-4F7D-A2D3-1E070FED04CD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9CA57C02-97B0-4C38-A027-EA61E8741F10} diff --git a/src/coverlet.datacollector/CoverletDataCollector.cs b/src/coverlet.datacollector/CoverletDataCollector.cs new file mode 100644 index 000000000..8faf39a7d --- /dev/null +++ b/src/coverlet.datacollector/CoverletDataCollector.cs @@ -0,0 +1,73 @@ +using Coverlet.Core.Instrumentation; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollector.InProcDataCollector; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.InProcDataCollector; +using System; +using System.Reflection; + +namespace Coverlet.DataCollector +{ + public class CoverletDataCollector : InProcDataCollection + { + public void Initialize(IDataCollectionSink dataCollectionSink) + { + } + + public void TestCaseEnd(TestCaseEndArgs testCaseEndArgs) + { + } + + public void TestCaseStart(TestCaseStartArgs testCaseStartArgs) + { + } + + public void TestSessionEnd(TestSessionEndArgs testSessionEndArgs) + { + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + Type injectedInstrumentationClass = GetInstrumentationClass(assembly); + if (injectedInstrumentationClass is null) + continue; + + var unloadModule = injectedInstrumentationClass.GetMethod(nameof(ModuleTrackerTemplate.UnloadModule), new[] { typeof(object), typeof(EventArgs) }); + if (unloadModule is null) + continue; + + try + { + unloadModule.Invoke(null, new[] { null, EventArgs.Empty }); + } + catch + { + // Ignore exceptions and continue with the unload + } + } + } + + public void TestSessionStart(TestSessionStartArgs testSessionStartArgs) + { + } + + private static Type GetInstrumentationClass(Assembly assembly) + { + try + { + foreach (var type in assembly.GetTypes()) + { + if (type.Namespace == "Coverlet.Core.Instrumentation.Tracker" + && type.Name.StartsWith(assembly.GetName().Name + "_")) + { + return type; + } + } + + return null; + } + catch + { + // Avoid crashing if reflection fails + return null; + } + } + } +} diff --git a/src/coverlet.datacollector/Properties/AssemblyInfo.cs b/src/coverlet.datacollector/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..13feffcbd --- /dev/null +++ b/src/coverlet.datacollector/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: System.Reflection.AssemblyKeyFileAttribute("coverlet.datacollector.snk")] \ No newline at end of file diff --git a/src/coverlet.datacollector/coverlet.datacollector.csproj b/src/coverlet.datacollector/coverlet.datacollector.csproj new file mode 100644 index 000000000..953812174 --- /dev/null +++ b/src/coverlet.datacollector/coverlet.datacollector.csproj @@ -0,0 +1,28 @@ + + + + + netcoreapp2.0 + 1.4.1 + tonerdo + $(AssemblyTitle) + $(AssemblyTitle) + Coverlet is a cross platform code coverage tool for .NET Core, with support for line, branch and method coverage. + $(AssemblyVersion) + coverage;testing;unit-test;lcov;opencover;quality + https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true + https://github.com/tonerdo/coverlet + https://github.com/tonerdo/coverlet/blob/master/LICENSE + git + https://github.com/tonerdo/coverlet + + + + + + + + + + + diff --git a/src/coverlet.datacollector/coverlet.datacollector.snk b/src/coverlet.datacollector/coverlet.datacollector.snk new file mode 100644 index 0000000000000000000000000000000000000000..1d67883c27e126c4616a021afa268336e6a0ca2f GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096YYc1lCsyKM4AKJS+%+yI*5zrDRmtx4k z8jws{i2JaUtWlrUi`B|gKn829&VeF1s~KID@=TsaREjR*}pPetHFbxuohxZle zx$mFAlMC$c^a))W+1dR(>H&4WRu!4Ov_QoK@`@}?IqN=|?89?54@$tj=L zkFP_FEjiLG{r!IePA{iA&nJ^puUuI|ap#i-F?Hoc5US^oF6~3hgEXB&M9>;)rQd=e z+mQPgy(r8=%$LT;-MHo1JK#pUV;pr{_f&=00qg@g$asYKg2!bQgMwb?ckJ8)>Xj3z z$iJLfgx~~$5<#{9N@FbLnhvz8)#aY0?-Rv>7!fH|Z8)FQhPqoIa z0S^~4A_-TQoN`lS8C)scU zlr5eeo~Afc{z`vj{CmiJ%0K{sW!_PcsP~Ok4D%5S`j~=umN%51;43T2SVo8&(0Six i?X2Qb$z?W?6}^2}5^)i$9H2|en>42hIp%Lvz{>+b+$3cH literal 0 HcmV?d00001