From 1ba7eb0c41b1279bf621ae1fdbe3058163106adf Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Sun, 21 May 2023 15:32:39 +0200 Subject: [PATCH] Added integration test # This is the 1st commit message: changes on test --- Documentation/Changelog.md | 6 ++ coverlet.sln | 25 +++++- .../Instrumentation/CecilAssemblyResolver.cs | 75 +++++++++++++++--- .../Instrumentation/InstrumenterResult.cs | 2 + src/coverlet.core/Properties/AssemblyInfo.cs | 5 +- .../Instrumentation/InstrumenterTests.cs | 32 ++------ .../ModuleTrackerTemplateTests.cs | 26 +++--- .../WpfResolverTests.cs | 45 +++++++++++ .../coverlet.integration.tests.csproj | 1 + .../AssemblyInfo.cs | 6 ++ .../ResolverTests.cs | 38 +++++++++ ...t.tests.projectsample.aspnet5.tests.csproj | 20 +++++ ...rlet.tests.projectsample.aspnet5.tests.snk | Bin 0 -> 596 bytes .../Program.cs | 23 ++++++ .../Startup.cs | 39 +++++++++ .../appsettings.Development.json | 9 +++ .../appsettings.json | 10 +++ ...overlet.tests.projectsample.aspnet5.csproj | 10 +++ .../TestClass.cs | 14 ++++ .../coverlet.tests.projectsample.wpf.csproj | 13 +++ 20 files changed, 344 insertions(+), 55 deletions(-) create mode 100644 test/coverlet.integration.tests/WpfResolverTests.cs create mode 100644 test/coverlet.tests.projectsample.aspnet5.tests/AssemblyInfo.cs create mode 100644 test/coverlet.tests.projectsample.aspnet5.tests/ResolverTests.cs create mode 100644 test/coverlet.tests.projectsample.aspnet5.tests/coverlet.tests.projectsample.aspnet5.tests.csproj create mode 100644 test/coverlet.tests.projectsample.aspnet5.tests/coverlet.tests.projectsample.aspnet5.tests.snk create mode 100644 test/coverlet.tests.projectsample.aspnet5/Program.cs create mode 100644 test/coverlet.tests.projectsample.aspnet5/Startup.cs create mode 100644 test/coverlet.tests.projectsample.aspnet5/appsettings.Development.json create mode 100644 test/coverlet.tests.projectsample.aspnet5/appsettings.json create mode 100644 test/coverlet.tests.projectsample.aspnet5/coverlet.tests.projectsample.aspnet5.csproj create mode 100644 test/coverlet.tests.projectsample.wpf/TestClass.cs create mode 100644 test/coverlet.tests.projectsample.wpf/coverlet.tests.projectsample.wpf.csproj diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index e02e8fd33..b31dfedac 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed +-Fix problem with coverage for .net5 WPF application [#1221](https://github.com/coverlet-coverage/coverlet/issues/1221) by https://github.com/lg2de +-Fix unable to instrument module for Microsoft.AspNetCore.Mvc.Razor [#1459](https://github.com/coverlet-coverage/coverlet/issues/1459) by https://github.com/lg2de + ## Release date 2023-05-21 ### Packages coverlet.msbuild 6.0.0 diff --git a/coverlet.sln b/coverlet.sln index efccfa31f..9a92d2d53 100644 --- a/coverlet.sln +++ b/coverlet.sln @@ -54,12 +54,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{9A8B19D4 test\Directory.Build.targets = test\Directory.Build.targets EndProjectSection EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "coverlet.tests.projectsample.vbmynamespace", "test\coverlet.tests.projectsample.vbmynamespace\coverlet.tests.projectsample.vbmynamespace.vbproj", "{C9B7DC34-3E04-4F20-AED4-73791AF8020D}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "coverlet.tests.projectsample.vbmynamespace", "test\coverlet.tests.projectsample.vbmynamespace\coverlet.tests.projectsample.vbmynamespace.vbproj", "{C9B7DC34-3E04-4F20-AED4-73791AF8020D}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "coverlet.tests.projectsample.fsharp", "test\coverlet.tests.projectsample.fsharp\coverlet.tests.projectsample.fsharp.fsproj", "{1CBF6966-2A67-4D2C-8598-D174B83072F4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "coverlet.tests.projectsample.netframework", "test\coverlet.tests.projectsample.netframework\coverlet.tests.projectsample.netframework.csproj", "{E69D68C9-78ED-4076-A14B-D07295A4B2A5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "coverlet.tests.projectsample.aspnet5", "test\coverlet.tests.projectsample.aspnet5\coverlet.tests.projectsample.aspnet5.csproj", "{1C3CA3F8-DF8C-433F-8A56-69102D2BBDF6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "coverlet.tests.projectsample.aspnet5.tests", "test\coverlet.tests.projectsample.aspnet5.tests\coverlet.tests.projectsample.aspnet5.tests.csproj", "{8EC065A4-7700-45E6-8B90-0182E3649DEA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "coverlet.tests.projectsample.wpf", "test\coverlet.tests.projectsample.wpf\coverlet.tests.projectsample.wpf.csproj", "{D2CB5A5E-2483-460B-A713-F5CBDD16D87C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -134,6 +140,18 @@ Global {E69D68C9-78ED-4076-A14B-D07295A4B2A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {E69D68C9-78ED-4076-A14B-D07295A4B2A5}.Release|Any CPU.ActiveCfg = Release|Any CPU {E69D68C9-78ED-4076-A14B-D07295A4B2A5}.Release|Any CPU.Build.0 = Release|Any CPU + {1C3CA3F8-DF8C-433F-8A56-69102D2BBDF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C3CA3F8-DF8C-433F-8A56-69102D2BBDF6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C3CA3F8-DF8C-433F-8A56-69102D2BBDF6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C3CA3F8-DF8C-433F-8A56-69102D2BBDF6}.Release|Any CPU.Build.0 = Release|Any CPU + {8EC065A4-7700-45E6-8B90-0182E3649DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8EC065A4-7700-45E6-8B90-0182E3649DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8EC065A4-7700-45E6-8B90-0182E3649DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8EC065A4-7700-45E6-8B90-0182E3649DEA}.Release|Any CPU.Build.0 = Release|Any CPU + {D2CB5A5E-2483-460B-A713-F5CBDD16D87C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2CB5A5E-2483-460B-A713-F5CBDD16D87C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2CB5A5E-2483-460B-A713-F5CBDD16D87C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2CB5A5E-2483-460B-A713-F5CBDD16D87C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -154,9 +172,12 @@ Global {5FF404AD-7C0B-465A-A1E9-558CDC642B0C} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} {F8199E19-FA9A-4559-9101-CAD7028121B4} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} {9A8B19D4-4A24-4217-AEFE-159B68F029A1} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} + {C9B7DC34-3E04-4F20-AED4-73791AF8020D} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} {1CBF6966-2A67-4D2C-8598-D174B83072F4} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} {E69D68C9-78ED-4076-A14B-D07295A4B2A5} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} - {C9B7DC34-3E04-4F20-AED4-73791AF8020D} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} + {1C3CA3F8-DF8C-433F-8A56-69102D2BBDF6} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} + {8EC065A4-7700-45E6-8B90-0182E3649DEA} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} + {D2CB5A5E-2483-460B-A713-F5CBDD16D87C} = {2FEBDE1B-83E3-445B-B9F8-5644B0E0E134} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9CA57C02-97B0-4C38-A027-EA61E8741F10} diff --git a/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs b/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs index 6a781485d..8c9d6dd41 100644 --- a/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs +++ b/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs @@ -10,6 +10,8 @@ using Microsoft.Extensions.DependencyModel; using Microsoft.Extensions.DependencyModel.Resolution; using Mono.Cecil; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Coverlet.Core.Instrumentation { @@ -70,14 +72,14 @@ public NetstandardAwareAssemblyResolver(string modulePath, ILogger logger) _modulePath = modulePath; _logger = logger; - // this is lazy because we cannot create AspNetCoreSharedFrameworkResolver if not on .NET Core runtime, + // this is lazy because we cannot create NetCoreSharedFrameworkResolver if not on .NET Core runtime, // runtime folders are different _compositeResolver = new Lazy(() => new CompositeCompilationAssemblyResolver(new ICompilationAssemblyResolver[] { new AppBaseCompilationAssemblyResolver(), + new NetCoreSharedFrameworkResolver(modulePath, _logger), new ReferenceAssemblyPathResolver(), new PackageCompilationAssemblyResolver(), - new AspNetCoreSharedFrameworkResolver(_logger) }), true); } @@ -216,23 +218,37 @@ internal AssemblyDefinition TryWithCustomResolverOnDotNetCore(AssemblyNameRefere } } - internal class AspNetCoreSharedFrameworkResolver : ICompilationAssemblyResolver + internal class NetCoreSharedFrameworkResolver : ICompilationAssemblyResolver { - private readonly string[] _aspNetSharedFrameworkDirs; + private readonly List _aspNetSharedFrameworkDirs = new(); private readonly ILogger _logger; - public AspNetCoreSharedFrameworkResolver(ILogger logger) + public NetCoreSharedFrameworkResolver(string modulePath, ILogger logger) { _logger = logger; - string runtimeRootPath = Path.GetDirectoryName(typeof(object).Assembly.Location); - string runtimeVersion = runtimeRootPath.Substring(runtimeRootPath.LastIndexOf(Path.DirectorySeparatorChar) + 1); - _aspNetSharedFrameworkDirs = new string[] + + string runtimeConfigFile = Path.Combine( + Path.GetDirectoryName(modulePath)!, + Path.GetFileNameWithoutExtension(modulePath) + ".runtimeconfig.json"); + if (!File.Exists(runtimeConfigFile)) + { + return; + } + + var reader = new RuntimeConfigurationReader(runtimeConfigFile); + IEnumerable<(string Name, string Version)> referencedFrameworks = reader.GetFrameworks(); + string runtimePath = Path.GetDirectoryName(typeof(object).Assembly.Location); + string runtimeRootPath = Path.Combine(runtimePath!, "../.."); + foreach ((string frameworkName, string frameworkVersion) in referencedFrameworks) { - Path.GetFullPath(Path.Combine(runtimeRootPath,"../../Microsoft.AspNetCore.All", runtimeVersion)), - Path.GetFullPath(Path.Combine(runtimeRootPath, "../../Microsoft.AspNetCore.App", runtimeVersion)) - }; + var majorVersion = string.Join(".", frameworkVersion.Split('.').Take(2)) + "."; + var directory = new DirectoryInfo(Path.Combine(runtimeRootPath, frameworkName)); + var latestVersion = directory.GetDirectories().Where(x => x.Name.StartsWith(majorVersion)) + .Select(x => Convert.ToUInt32(x.Name.Substring(majorVersion.Length))).Max(); + _aspNetSharedFrameworkDirs.Add(Path.Combine(directory.FullName, majorVersion + latestVersion)); + } - _logger.LogVerbose("AspNetCoreSharedFrameworkResolver search paths:"); + _logger.LogVerbose("NetCoreSharedFrameworkResolver search paths:"); foreach (string searchPath in _aspNetSharedFrameworkDirs) { _logger.LogVerbose(searchPath); @@ -250,7 +266,8 @@ public bool TryResolveAssemblyPaths(CompilationLibrary library, List ass continue; } - foreach (string file in Directory.GetFiles(sharedFrameworkPath)) + string[] files = Directory.GetFiles(sharedFrameworkPath); + foreach (string file in files) { if (Path.GetFileName(file).Equals(dllName, StringComparison.OrdinalIgnoreCase)) { @@ -264,4 +281,36 @@ public bool TryResolveAssemblyPaths(CompilationLibrary library, List ass return false; } } + + internal class RuntimeConfigurationReader + { + private readonly string _runtimeConfigFile; + + public RuntimeConfigurationReader(string runtimeConfigFile) + { + _runtimeConfigFile = runtimeConfigFile; + } + + public IEnumerable<(string Name, string Version)> GetFrameworks() + { + JObject configuration = + new JsonSerializer().Deserialize( + new JsonTextReader(new StringReader(File.ReadAllText(_runtimeConfigFile)))); + + JToken runtimeOptions = configuration["runtimeOptions"]; + JToken framework = runtimeOptions?["framework"]; + if (framework != null) + { + return new[] {(framework["name"].Value(), framework["version"].Value())}; + } + + JToken frameworks = runtimeOptions?["frameworks"]; + if (frameworks != null) + { + return frameworks.Select(x => (x["name"].Value(), x["version"].Value())); + } + + throw new InvalidOperationException($"Unable to read runtime configuration from {_runtimeConfigFile}."); + } + } } diff --git a/src/coverlet.core/Instrumentation/InstrumenterResult.cs b/src/coverlet.core/Instrumentation/InstrumenterResult.cs index 69a6ab24a..f93b66866 100644 --- a/src/coverlet.core/Instrumentation/InstrumenterResult.cs +++ b/src/coverlet.core/Instrumentation/InstrumenterResult.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.Serialization; namespace Coverlet.Core.Instrumentation @@ -79,6 +80,7 @@ public Document() [DebuggerDisplay("isBranch = {isBranch} docIndex = {docIndex} start = {start} end = {end}")] [DataContract] + [SuppressMessage("Style", "IDE1006", Justification = "suppress casing error for API compatibility")] internal class HitCandidate { public HitCandidate(bool isBranch, int docIndex, int start, int end) => (this.isBranch, this.docIndex, this.start, this.end) = (isBranch, docIndex, start, end); diff --git a/src/coverlet.core/Properties/AssemblyInfo.cs b/src/coverlet.core/Properties/AssemblyInfo.cs index 7e65be514..d14322608 100644 --- a/src/coverlet.core/Properties/AssemblyInfo.cs +++ b/src/coverlet.core/Properties/AssemblyInfo.cs @@ -13,5 +13,8 @@ [assembly: InternalsVisibleTo("coverlet.core.tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100757cf9291d78a82e5bb58a827a3c46c2f959318327ad30d1b52e918321ffbd847fb21565b8576d2a3a24562a93e86c77a298b564a0f1b98f63d7a1441a3a8bcc206da3ed09d5dacc76e122a109a9d3ac608e21a054d667a2bae98510a1f0f653c0e6f58f42b4b3934f6012f5ec4a09b3dfd3e14d437ede1424bdb722aead64ad")] [assembly: InternalsVisibleTo("coverlet.collector.tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100ed0ed6af9693182615b8dcadc83c918b8d36312f86cefc69539d67d4189cd1b89420e7c3871802ffef7f5ca7816c68ad856c77bf7c230cc07824d96aa5d1237eebd30e246b9a14e22695fb26b40c800f74ea96619092cbd3a5d430d6c003fc7a82e8ccd1e315b935105d9232fe9e99e8d7ff54bba6f191959338d4a3169df9b3")] [assembly: InternalsVisibleTo("coverlet.integration.tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010001d24efbe9cbc2dc49b7a3d2ae34ca37cfb69b4f450acd768a22ce5cd021c8a38ae7dc68b2809a1ac606ad531b578f192a5690b2986990cbda4dd84ec65a3a4c1c36f6d7bb18f08592b93091535eaee2f0c8e48763ed7f190db2008e1f9e0facd5c0df5aaab74febd3430e09a428a72e5e6b88357f92d78e47512d46ebdc3cbb")] +[assembly: InternalsVisibleTo("coverlet.tests.projectsample.aspnet5.tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100757cf9291d78a82e5bb58a827a3c46c2f959318327ad30d1b52e918321ffbd847fb21565b8576d2a3a24562a93e86c77a298b564a0f1b98f63d7a1441a3a8bcc206da3ed09d5dacc76e122a109a9d3ac608e21a054d667a2bae98510a1f0f653c0e6f58f42b4b3934f6012f5ec4a09b3dfd3e14d437ede1424bdb722aead64ad")] +[assembly: InternalsVisibleTo("coverlet.tests.projectsample.wpf5.tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100757cf9291d78a82e5bb58a827a3c46c2f959318327ad30d1b52e918321ffbd847fb21565b8576d2a3a24562a93e86c77a298b564a0f1b98f63d7a1441a3a8bcc206da3ed09d5dacc76e122a109a9d3ac608e21a054d667a2bae98510a1f0f653c0e6f58f42b4b3934f6012f5ec4a09b3dfd3e14d437ede1424bdb722aead64ad")] + // Needed to mock internal type https://github.com/Moq/moq4/wiki/Quickstart#advanced-features -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] \ No newline at end of file +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs index a8c31da33..c561e3a5f 100644 --- a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs +++ b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs @@ -619,24 +619,6 @@ public int SampleMethod() if (expectedExcludes) { loggerMock.Verify(l => l.LogVerbose(It.IsAny())); } } - [Fact] - public void TestInstrument_AspNetCoreSharedFrameworkResolver() - { - var resolver = new AspNetCoreSharedFrameworkResolver(_mockLogger.Object); - var compilationLibrary = new CompilationLibrary( - "package", - "Microsoft.Extensions.Logging.Abstractions", - "2.2.0", - "sha512-B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A==", - Enumerable.Empty(), - Enumerable.Empty(), - true); - - var assemblies = new List(); - Assert.True(resolver.TryResolveAssemblyPaths(compilationLibrary, assemblies)); - Assert.NotEmpty(assemblies); - } - [Fact] public void TestInstrument_NetstandardAwareAssemblyResolver_PreserveCompilationContext() { @@ -740,15 +722,15 @@ public void TestReachabilityHelper() new[] { // Throws - 7, 8, + 7, 8, // NoBranches - 12, 13, 14, 15, 16, + 12, 13, 14, 15, 16, // If - 19, 20, 22, 23, 24, 25, 26, 27, 29, 30, + 19, 20, 22, 23, 24, 25, 26, 27, 29, 30, // Switch - 33, 34, 36, 39, 40, 41, 42, 44, 45, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 64, 65, 68, 69, + 33, 34, 36, 39, 40, 41, 42, 44, 45, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 64, 65, 68, 69, // Subtle - 72, 73, 75, 78, 79, 80, 82, 83, 86, 87, 88, 91, 92, 95, 96, 98, 99, 101, 102, 103, + 72, 73, 75, 78, 79, 80, 82, 83, 86, 87, 88, 91, 92, 95, 96, 98, 99, 101, 102, 103, // UnreachableBranch 106, 107, 108, 110, 111, 112, 113, 114, // ThrowsGeneric @@ -774,7 +756,7 @@ public void TestReachabilityHelper() // Switch 41, 42, // Subtle - 79, 80, 88, 96, 98, 99, + 79, 80, 88, 96, 98, 99, // UnreachableBranch 110, 111, 112, 113, 114, // CallsGenericMethodDoesNotReturn @@ -822,7 +804,7 @@ public void Instrumenter_MethodsWithoutReferenceToSource_AreSkipped() var instrumenter = new Instrumenter(Path.Combine(directory.FullName, Path.GetFileName(module)), "_coverlet_tests_projectsample_vbmynamespace", parameters, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(Path.Combine(directory.FullName, Path.GetFileName(module)), loggerMock.Object, new FileSystem(), new AssemblyAdapter()), new CecilSymbolHelper()); - + instrumentationHelper.BackupOriginalModule(Path.Combine(directory.FullName, Path.GetFileName(module)), "_coverlet_tests_projectsample_vbmynamespace"); InstrumenterResult result = instrumenter.Instrument(); diff --git a/test/coverlet.core.tests/Instrumentation/ModuleTrackerTemplateTests.cs b/test/coverlet.core.tests/Instrumentation/ModuleTrackerTemplateTests.cs index 7cd5f2943..677ead26b 100644 --- a/test/coverlet.core.tests/Instrumentation/ModuleTrackerTemplateTests.cs +++ b/test/coverlet.core.tests/Instrumentation/ModuleTrackerTemplateTests.cs @@ -123,26 +123,24 @@ public void MutexBlocksMultipleWriters() FunctionExecutor.Run(async () => { using var ctx = new TrackerContext(); - using (var mutex = new Mutex( - true, Path.GetFileNameWithoutExtension(ModuleTrackerTemplate.HitsFilePath) + "_Mutex", out bool createdNew)) - { - Assert.True(createdNew); + using var mutex = new Mutex( + true, Path.GetFileNameWithoutExtension(ModuleTrackerTemplate.HitsFilePath) + "_Mutex", out bool createdNew); + Assert.True(createdNew); - ModuleTrackerTemplate.HitsArray = new[] { 0, 1, 2, 3 }; - var unloadTask = Task.Run(() => ModuleTrackerTemplate.UnloadModule(null, null)); + ModuleTrackerTemplate.HitsArray = new[] { 0, 1, 2, 3 }; + var unloadTask = Task.Run(() => ModuleTrackerTemplate.UnloadModule(null, null)); - Assert.False(unloadTask.Wait(5)); + Assert.False(unloadTask.Wait(5)); - WriteHitsFile(new[] { 0, 3, 2, 1 }); + WriteHitsFile(new[] { 0, 3, 2, 1 }); - Assert.False(unloadTask.Wait(5)); + Assert.False(unloadTask.Wait(5)); - mutex.ReleaseMutex(); - await unloadTask; + mutex.ReleaseMutex(); + await unloadTask; - int[] expectedHitsArray = new[] { 0, 4, 4, 4 }; - Assert.Equal(expectedHitsArray, ReadHitsFile()); - } + int[] expectedHitsArray = new[] { 0, 4, 4, 4 }; + Assert.Equal(expectedHitsArray, ReadHitsFile()); return 0; }); diff --git a/test/coverlet.integration.tests/WpfResolverTests.cs b/test/coverlet.integration.tests/WpfResolverTests.cs new file mode 100644 index 000000000..7bb4cd15c --- /dev/null +++ b/test/coverlet.integration.tests/WpfResolverTests.cs @@ -0,0 +1,45 @@ +// Copyright (c) Toni Solarin-Sodara +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Coverlet.Core.Abstractions; +using Coverlet.Core.Instrumentation; +using Coverlet.Integration.Tests; +using Coverlet.Tests.Xunit.Extensions; +using Microsoft.Extensions.DependencyModel; +using Moq; +using Xunit; + +namespace coverlet.integration.tests +{ + public class WpfResolverTests : BaseTest + { + [ConditionalFact] + [SkipOnOS(OS.Linux, "WPF only runs on Windows")] + [SkipOnOS(OS.MacOS, "WPF only runs on Windows")] + public void TestInstrument_NetCoreSharedFrameworkResolver() + { + string wpfProjectPath = "../../../../coverlet.tests.projectsample.wpf"; + DotnetCli($"build \"{wpfProjectPath}\"", out string _, out string _); + string assemblyLocation = Directory.GetFiles($"{wpfProjectPath}/bin", "coverlet.tests.projectsample.wpf.dll", SearchOption.AllDirectories).First(); + + var mockLogger = new Mock(); + var resolver = new NetCoreSharedFrameworkResolver(assemblyLocation, mockLogger.Object); + var compilationLibrary = new CompilationLibrary( + "package", + "System.Drawing", + "5.0.17.0", + "sha512-B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A==", + Enumerable.Empty(), + Enumerable.Empty(), + true); + + var assemblies = new List(); + Assert.True(resolver.TryResolveAssemblyPaths(compilationLibrary, assemblies), + $"sample assembly shall be resolved - AssemblyLocation: {assemblyLocation}"); + Assert.NotEmpty(assemblies); + } + } +} diff --git a/test/coverlet.integration.tests/coverlet.integration.tests.csproj b/test/coverlet.integration.tests/coverlet.integration.tests.csproj index 6de30285a..32c490e66 100644 --- a/test/coverlet.integration.tests/coverlet.integration.tests.csproj +++ b/test/coverlet.integration.tests/coverlet.integration.tests.csproj @@ -10,6 +10,7 @@ + diff --git a/test/coverlet.tests.projectsample.aspnet5.tests/AssemblyInfo.cs b/test/coverlet.tests.projectsample.aspnet5.tests/AssemblyInfo.cs new file mode 100644 index 000000000..4192d1b1e --- /dev/null +++ b/test/coverlet.tests.projectsample.aspnet5.tests/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Toni Solarin-Sodara +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Reflection; + +[assembly: AssemblyKeyFile("coverlet.tests.projectsample.aspnet5.tests.snk")] diff --git a/test/coverlet.tests.projectsample.aspnet5.tests/ResolverTests.cs b/test/coverlet.tests.projectsample.aspnet5.tests/ResolverTests.cs new file mode 100644 index 000000000..bda6360f7 --- /dev/null +++ b/test/coverlet.tests.projectsample.aspnet5.tests/ResolverTests.cs @@ -0,0 +1,38 @@ +// Copyright (c) Toni Solarin-Sodara +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Coverlet.Core.Abstractions; +using Coverlet.Core.Instrumentation; +using Microsoft.Extensions.DependencyModel; +using Moq; +using Xunit; + +namespace coverlet.tests.projectsample.aspnet5.tests +{ + public class ResolverTests + { + [Fact] + public void TestInstrument_NetCoreSharedFrameworkResolver() + { + Assembly assembly = GetType().Assembly; + var mockLogger = new Mock(); + var resolver = new NetCoreSharedFrameworkResolver(assembly.Location, mockLogger.Object); + var compilationLibrary = new CompilationLibrary( + "package", + "Microsoft.Extensions.Logging.Abstractions", + "2.2.0", + "sha512-B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A==", + Enumerable.Empty(), + Enumerable.Empty(), + true); + + var assemblies = new List(); + Assert.True(resolver.TryResolveAssemblyPaths(compilationLibrary, assemblies), + "sample assembly shall be resolved"); + Assert.NotEmpty(assemblies); + } + } +} diff --git a/test/coverlet.tests.projectsample.aspnet5.tests/coverlet.tests.projectsample.aspnet5.tests.csproj b/test/coverlet.tests.projectsample.aspnet5.tests/coverlet.tests.projectsample.aspnet5.tests.csproj new file mode 100644 index 000000000..d69b11ac7 --- /dev/null +++ b/test/coverlet.tests.projectsample.aspnet5.tests/coverlet.tests.projectsample.aspnet5.tests.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + false + + + + + + + + + + + + + + + diff --git a/test/coverlet.tests.projectsample.aspnet5.tests/coverlet.tests.projectsample.aspnet5.tests.snk b/test/coverlet.tests.projectsample.aspnet5.tests/coverlet.tests.projectsample.aspnet5.tests.snk new file mode 100644 index 0000000000000000000000000000000000000000..9e007898b54599bc8a77f98b601b9dc05591dcf0 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097XeEBIIc&IL0wTgmzJVwI#SuukrtuWEG zE|G&F|Gk8NvK3{xS8XafBvvYu=xleQn6+e}@wty<*P%ojI*ZI8ZKLf8)!NK<;Ub|4 zsne`rjv=5_)@P!+>4gxX@b*){=Jk(4w6l{>U=sE0N(r;y)8S1+e%=%$y|*H+tz@mA zX+_07fMQLKaP7!3t*el!1Pr0eatN2ScEC4In}@tC$1f@F>m~RNA}Z=sTPi~SASR!N z2BK{p8v!Va4Q$72Nhnt7C9-ey&2T~|#vkpsYPH_@jVd3kt45})`+5j+_lP3AOYzP- z#_(UOwVG2={VwN=Z0OH8b2kj)DVE+BEwUn@L^bx#blR<_D&JGO2$+$Bf2fPzSA4DX zqy^KhFQLFn3n}U80Cjgh3Jy%TvEC>m8d}j$vMJF8Yz>6(wOy@nY9x@0qHTA6-S*#l zmb!ewwR$Urib?u<#q<&V2$~=60O$m8uz`=rQq^I|@`uL1Yl4(Dx2Etz={USc^Ym85 z#piE9H5c&6o_cx%oo@qx(UPV)vT#$3k}B@@U64RD8BB;n#VNe(fGnhlmIsNXXEF&_ zTo}Z;JPeS9tEybm8I+RFl>?0^n<0ZjeDk}O+hQYvSmV9BW@h zM}7567D^tzfyW+DXu literal 0 HcmV?d00001 diff --git a/test/coverlet.tests.projectsample.aspnet5/Program.cs b/test/coverlet.tests.projectsample.aspnet5/Program.cs new file mode 100644 index 000000000..39a4e2805 --- /dev/null +++ b/test/coverlet.tests.projectsample.aspnet5/Program.cs @@ -0,0 +1,23 @@ +// Copyright (c) Toni Solarin-Sodara +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace coverlet.tests.projectsample.aspnet5 +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/test/coverlet.tests.projectsample.aspnet5/Startup.cs b/test/coverlet.tests.projectsample.aspnet5/Startup.cs new file mode 100644 index 000000000..04bdb3b54 --- /dev/null +++ b/test/coverlet.tests.projectsample.aspnet5/Startup.cs @@ -0,0 +1,39 @@ +// Copyright (c) Toni Solarin-Sodara +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace coverlet.tests.projectsample.aspnet5 +{ + public class Startup + { + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) + { + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", async context => + { + await context.Response.WriteAsync("Hello World!"); + }); + }); + } + } +} diff --git a/test/coverlet.tests.projectsample.aspnet5/appsettings.Development.json b/test/coverlet.tests.projectsample.aspnet5/appsettings.Development.json new file mode 100644 index 000000000..8983e0fc1 --- /dev/null +++ b/test/coverlet.tests.projectsample.aspnet5/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/test/coverlet.tests.projectsample.aspnet5/appsettings.json b/test/coverlet.tests.projectsample.aspnet5/appsettings.json new file mode 100644 index 000000000..d9d9a9bff --- /dev/null +++ b/test/coverlet.tests.projectsample.aspnet5/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/test/coverlet.tests.projectsample.aspnet5/coverlet.tests.projectsample.aspnet5.csproj b/test/coverlet.tests.projectsample.aspnet5/coverlet.tests.projectsample.aspnet5.csproj new file mode 100644 index 000000000..19ead24ac --- /dev/null +++ b/test/coverlet.tests.projectsample.aspnet5/coverlet.tests.projectsample.aspnet5.csproj @@ -0,0 +1,10 @@ + + + + net6.0 + false + false + false + + + diff --git a/test/coverlet.tests.projectsample.wpf/TestClass.cs b/test/coverlet.tests.projectsample.wpf/TestClass.cs new file mode 100644 index 000000000..a86ddccb0 --- /dev/null +++ b/test/coverlet.tests.projectsample.wpf/TestClass.cs @@ -0,0 +1,14 @@ +// Copyright (c) Toni Solarin-Sodara +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Windows.Controls; + +namespace coverlet.tests.projectsample.wpf +{ + public class TestClass + { + public static void Main(){} + + public UserControl Control { get; set; } = null!; + } +} diff --git a/test/coverlet.tests.projectsample.wpf/coverlet.tests.projectsample.wpf.csproj b/test/coverlet.tests.projectsample.wpf/coverlet.tests.projectsample.wpf.csproj new file mode 100644 index 000000000..c7e801a61 --- /dev/null +++ b/test/coverlet.tests.projectsample.wpf/coverlet.tests.projectsample.wpf.csproj @@ -0,0 +1,13 @@ + + + + WinExe + net6.0-windows + enable + true + false + false + true + + +