Increase severity of some rules and fix instances (#1305)

Increase severity of some rules and fix instances
This commit is contained in:
Amaury Levé
2022-02-24 11:23:41 +01:00
committed by GitHub
parent 76ffde3624
commit 2bb04f21ec
25 changed files with 400 additions and 422 deletions
+18
View File
@@ -87,6 +87,20 @@ dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
# CA1805: Do not initialize unnecessarily
dotnet_diagnostic.CA1805.severity = warning
# IDE0063: Use simple 'using' statement
dotnet_diagnostic.IDE0063.severity = warning
# IDE0057: Use range operator
dotnet_diagnostic.IDE0057.severity = warning
# IDE0075: Simplify conditional expression
dotnet_diagnostic.IDE0075.severity = warning
# IDE0071: Simplify interpolation
dotnet_diagnostic.IDE0071.severity = warning
# CA1829: Use Length/Count property instead of Count() when available
dotnet_diagnostic.CA1829.severity = warning
# CA1827: Do not use Count() or LongCount() when Any() can be used
dotnet_diagnostic.CA1827.severity = warning
###############################
# Naming Conventions #
###############################
@@ -114,6 +128,10 @@ dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
# IDE1006: Naming Styles
dotnet_diagnostic.IDE1006.severity = warning
# IDE0090: Use 'new(...)'
dotnet_diagnostic.IDE0090.severity = warning
###############################
# C# Coding Conventions #
###############################
@@ -163,17 +163,15 @@ namespace Coverlet.Collector.DataCollection
// Get coverage reports
IEnumerable<(string report, string fileName)> coverageReports = _coverageManager?.GetCoverageReports();
if (coverageReports != null && coverageReports.Count() > 0)
if (coverageReports != null && coverageReports.Any())
{
// Send result attachments to test platform.
using (var attachmentManager = new AttachmentManager(_dataSink, _dataCollectionContext, _logger, _eqtTrace, _countDownEventFactory.Create(coverageReports.Count(), TimeSpan.FromSeconds(30))))
{
using var attachmentManager = new AttachmentManager(_dataSink, _dataCollectionContext, _logger, _eqtTrace, _countDownEventFactory.Create(coverageReports.Count(), TimeSpan.FromSeconds(30)));
foreach ((string report, string fileName) in coverageReports)
{
attachmentManager.SendCoverageReport(report, fileName);
}
}
}
else
{
_eqtTrace.Verbose("{0}: No coverage reports specified", CoverletConstants.DataCollectorName);
@@ -66,7 +66,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="testModules">Test modules</param>
/// <returns>Test module</returns>
private string ParseTestModule(IEnumerable<string> testModules)
private static string ParseTestModule(IEnumerable<string> testModules)
{
// Validate if at least one source present.
if (testModules == null || !testModules.Any())
@@ -86,7 +86,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Report formats</returns>
private string[] ParseReportFormats(XmlElement configurationElement)
private static string[] ParseReportFormats(XmlElement configurationElement)
{
string[] formats = Array.Empty<string>();
if (configurationElement != null)
@@ -103,7 +103,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Filters to include</returns>
private string[] ParseIncludeFilters(XmlElement configurationElement)
private static string[] ParseIncludeFilters(XmlElement configurationElement)
{
XmlElement includeFiltersElement = configurationElement[CoverletConstants.IncludeFiltersElementName];
return SplitElement(includeFiltersElement);
@@ -114,7 +114,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Directories to include</returns>
private string[] ParseIncludeDirectories(XmlElement configurationElement)
private static string[] ParseIncludeDirectories(XmlElement configurationElement)
{
XmlElement includeDirectoriesElement = configurationElement[CoverletConstants.IncludeDirectoriesElementName];
return SplitElement(includeDirectoriesElement);
@@ -125,7 +125,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Filters to exclude</returns>
private string[] ParseExcludeFilters(XmlElement configurationElement)
private static string[] ParseExcludeFilters(XmlElement configurationElement)
{
var excludeFilters = new List<string> { CoverletConstants.DefaultExcludeFilter };
@@ -147,7 +147,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Source files to exclude</returns>
private string[] ParseExcludeSourceFiles(XmlElement configurationElement)
private static string[] ParseExcludeSourceFiles(XmlElement configurationElement)
{
XmlElement excludeSourceFilesElement = configurationElement[CoverletConstants.ExcludeSourceFilesElementName];
return SplitElement(excludeSourceFilesElement);
@@ -158,7 +158,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Attributes to exclude</returns>
private string[] ParseExcludeAttributes(XmlElement configurationElement)
private static string[] ParseExcludeAttributes(XmlElement configurationElement)
{
XmlElement excludeAttributesElement = configurationElement[CoverletConstants.ExcludeAttributesElementName];
return SplitElement(excludeAttributesElement);
@@ -169,7 +169,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Merge with attribute</returns>
private string ParseMergeWith(XmlElement configurationElement)
private static string ParseMergeWith(XmlElement configurationElement)
{
XmlElement mergeWithElement = configurationElement[CoverletConstants.MergeWithElementName];
return mergeWithElement?.InnerText;
@@ -180,7 +180,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Use source link flag</returns>
private bool ParseUseSourceLink(XmlElement configurationElement)
private static bool ParseUseSourceLink(XmlElement configurationElement)
{
XmlElement useSourceLinkElement = configurationElement[CoverletConstants.UseSourceLinkElementName];
bool.TryParse(useSourceLinkElement?.InnerText, out bool useSourceLink);
@@ -192,7 +192,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Single hit flag</returns>
private bool ParseSingleHit(XmlElement configurationElement)
private static bool ParseSingleHit(XmlElement configurationElement)
{
XmlElement singleHitElement = configurationElement[CoverletConstants.SingleHitElementName];
bool.TryParse(singleHitElement?.InnerText, out bool singleHit);
@@ -204,7 +204,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>ParseDeterministicReport flag</returns>
private bool ParseDeterministicReport(XmlElement configurationElement)
private static bool ParseDeterministicReport(XmlElement configurationElement)
{
XmlElement deterministicReportElement = configurationElement[CoverletConstants.DeterministicReport];
bool.TryParse(deterministicReportElement?.InnerText, out bool deterministicReport);
@@ -216,7 +216,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Include Test Assembly Flag</returns>
private bool ParseIncludeTestAssembly(XmlElement configurationElement)
private static bool ParseIncludeTestAssembly(XmlElement configurationElement)
{
XmlElement includeTestAssemblyElement = configurationElement[CoverletConstants.IncludeTestAssemblyElementName];
bool.TryParse(includeTestAssemblyElement?.InnerText, out bool includeTestAssembly);
@@ -228,7 +228,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Include Test Assembly Flag</returns>
private bool ParseSkipAutoProps(XmlElement configurationElement)
private static bool ParseSkipAutoProps(XmlElement configurationElement)
{
XmlElement skipAutoPropsElement = configurationElement[CoverletConstants.SkipAutoProps];
bool.TryParse(skipAutoPropsElement?.InnerText, out bool skipAutoProps);
@@ -240,7 +240,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>DoesNotReturn attributes</returns>
private string[] ParseDoesNotReturnAttributes(XmlElement configurationElement)
private static string[] ParseDoesNotReturnAttributes(XmlElement configurationElement)
{
XmlElement doesNotReturnAttributesElement = configurationElement[CoverletConstants.DoesNotReturnAttributesElementName];
return SplitElement(doesNotReturnAttributesElement);
@@ -251,7 +251,7 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
/// <param name="element">The element to split</param>
/// <returns>An array of the values in the element</returns>
private string[] SplitElement(XmlElement element)
private static string[] SplitElement(XmlElement element)
{
return element?.InnerText?.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Where(value => !string.IsNullOrWhiteSpace(value)).Select(value => value.Trim()).ToArray();
}
@@ -17,7 +17,7 @@ namespace Coverlet.Collector.DataCollection
public class CoverletInProcDataCollector : InProcDataCollection
{
private TestPlatformEqtTrace _eqtTrace;
private bool _enableExceptionLog = false;
private bool _enableExceptionLog;
private void AttachDebugger()
{
@@ -9,7 +9,8 @@ namespace Coverlet.Console.Logging
{
class ConsoleLogger : ILogger
{
private static readonly object _sync = new object();
private static readonly object s_sync = new();
public LogLevel Level { get; set; } = LogLevel.Normal;
public void LogError(string message) => Log(LogLevel.Quiet, message, ConsoleColor.Red);
@@ -26,7 +27,7 @@ namespace Coverlet.Console.Logging
{
if (level < Level) return;
lock (_sync)
lock (s_sync)
{
ConsoleColor currentForegroundColor;
if (color != (currentForegroundColor = ForegroundColor))
+1 -1
View File
@@ -330,7 +330,7 @@ namespace Coverlet.Core
return false;
}
private Method GetMethodWithSameLineInSameDocument(Classes documentClasses, string compilerGeneratedClassName, int branchLine)
private static Method GetMethodWithSameLineInSameDocument(Classes documentClasses, string compilerGeneratedClassName, int branchLine)
{
foreach (KeyValuePair<string, Methods> @class in documentClasses)
{
@@ -18,7 +18,7 @@ namespace Coverlet.Core.Helpers
internal class InstrumentationHelper : IInstrumentationHelper
{
private const int RetryAttempts = 12;
private readonly ConcurrentDictionary<string, string> _backupList = new ConcurrentDictionary<string, string>();
private readonly ConcurrentDictionary<string, string> _backupList = new();
private readonly IRetryHelper _retryHelper;
private readonly IFileSystem _fileSystem;
private readonly ISourceRootTranslator _sourceRootTranslator;
@@ -83,9 +83,8 @@ namespace Coverlet.Core.Helpers
public bool HasPdb(string module, out bool embedded)
{
embedded = false;
using (Stream moduleStream = _fileSystem.OpenRead(module))
using (var peReader = new PEReader(moduleStream))
{
using Stream moduleStream = _fileSystem.OpenRead(module);
using var peReader = new PEReader(moduleStream);
foreach (DebugDirectoryEntry entry in peReader.ReadDebugDirectory())
{
if (entry.Type == DebugDirectoryEntryType.CodeView)
@@ -104,7 +103,6 @@ namespace Coverlet.Core.Helpers
return false;
}
}
public bool EmbeddedPortablePdbHasLocalSource(string module, out string firstNotFoundDocument)
{
@@ -116,8 +114,7 @@ namespace Coverlet.Core.Helpers
{
if (entry.Type == DebugDirectoryEntryType.EmbeddedPortablePdb)
{
using (MetadataReaderProvider embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(entry))
{
using MetadataReaderProvider embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(entry);
MetadataReader metadataReader = embeddedMetadataProvider.GetMetadataReader();
(bool allDocumentsMatch, string notFoundDocument) = MatchDocumentsWithSources(metadataReader);
@@ -130,7 +127,6 @@ namespace Coverlet.Core.Helpers
}
}
}
}
// If we don't have EmbeddedPortablePdb entry return true, for instance empty dll
// We should call this method only on embedded pdb module
@@ -388,7 +384,7 @@ namespace Coverlet.Core.Helpers
_logger = logger;
}
private bool IsTypeFilterMatch(string module, string type, string[] filters)
private static bool IsTypeFilterMatch(string module, string type, string[] filters)
{
Debug.Assert(module != null);
Debug.Assert(filters != null);
@@ -408,7 +404,7 @@ namespace Coverlet.Core.Helpers
return false;
}
private string GetBackupPath(string module, string identifier)
private static string GetBackupPath(string module, string identifier)
{
return Path.Combine(
Path.GetTempPath(),
@@ -428,14 +424,14 @@ namespace Coverlet.Core.Helpers
return retryStrategy;
}
private string WildcardToRegex(string pattern)
private static string WildcardToRegex(string pattern)
{
return "^" + Regex.Escape(pattern).
Replace("\\*", ".*").
Replace("\\?", "?") + "$";
}
private bool IsAssembly(string filePath)
private static bool IsAssembly(string filePath)
{
Debug.Assert(filePath != null);
@@ -453,7 +449,7 @@ namespace Coverlet.Core.Helpers
}
}
private bool IsUnknownModuleInFSharpAssembly(Guid languageGuid, string docName)
private static bool IsUnknownModuleInFSharpAssembly(Guid languageGuid, string docName)
{
// https://github.com/dotnet/runtime/blob/main/docs/design/specs/PortablePdb-Metadata.md#document-table-0x30
return languageGuid.Equals(new Guid("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3"))
@@ -48,7 +48,7 @@ namespace Coverlet.Core.Helpers
_sourceToDeterministicPathMapping = LoadSourceToDeterministicPathMapping(_sourceRootMapping);
}
private Dictionary<string, List<string>> LoadSourceToDeterministicPathMapping(Dictionary<string, List<SourceRootMapping>> sourceRootMapping)
private static Dictionary<string, List<string>> LoadSourceToDeterministicPathMapping(Dictionary<string, List<SourceRootMapping>> sourceRootMapping)
{
if (sourceRootMapping is null)
{
@@ -39,10 +39,10 @@ namespace Coverlet.Core.Instrumentation
/// </summary>
internal class NetstandardAwareAssemblyResolver : DefaultAssemblyResolver
{
private static readonly System.Reflection.Assembly _netStandardAssembly;
private static readonly string _name;
private static readonly byte[] _publicKeyToken;
private static readonly AssemblyDefinition _assemblyDefinition;
private static readonly System.Reflection.Assembly s_netStandardAssembly;
private static readonly string s_name;
private static readonly byte[] s_publicKeyToken;
private static readonly AssemblyDefinition s_assemblyDefinition;
private readonly string _modulePath;
private readonly Lazy<CompositeCompilationAssemblyResolver> _compositeResolver;
@@ -53,11 +53,11 @@ namespace Coverlet.Core.Instrumentation
try
{
// To be sure to load information of "real" runtime netstandard implementation
_netStandardAssembly = System.Reflection.Assembly.LoadFile(Path.Combine(Path.GetDirectoryName(typeof(object).Assembly.Location), "netstandard.dll"));
System.Reflection.AssemblyName name = _netStandardAssembly.GetName();
_name = name.Name;
_publicKeyToken = name.GetPublicKeyToken();
_assemblyDefinition = AssemblyDefinition.ReadAssembly(_netStandardAssembly.Location);
s_netStandardAssembly = System.Reflection.Assembly.LoadFile(Path.Combine(Path.GetDirectoryName(typeof(object).Assembly.Location), "netstandard.dll"));
System.Reflection.AssemblyName name = s_netStandardAssembly.GetName();
s_name = name.Name;
s_publicKeyToken = name.GetPublicKeyToken();
s_assemblyDefinition = AssemblyDefinition.ReadAssembly(s_netStandardAssembly.Location);
}
catch (FileNotFoundException)
{
@@ -82,26 +82,26 @@ namespace Coverlet.Core.Instrumentation
}
// Check name and public key but not version that could be different
private bool CheckIfSearchingNetstandard(AssemblyNameReference name)
private static bool CheckIfSearchingNetstandard(AssemblyNameReference name)
{
if (_netStandardAssembly is null)
if (s_netStandardAssembly is null)
{
return false;
}
if (_name != name.Name)
if (s_name != name.Name)
{
return false;
}
if (name.PublicKeyToken.Length != _publicKeyToken.Length)
if (name.PublicKeyToken.Length != s_publicKeyToken.Length)
{
return false;
}
for (int i = 0; i < name.PublicKeyToken.Length; i++)
{
if (_publicKeyToken[i] != name.PublicKeyToken[i])
if (s_publicKeyToken[i] != name.PublicKeyToken[i])
{
return false;
}
@@ -114,7 +114,7 @@ namespace Coverlet.Core.Instrumentation
{
if (CheckIfSearchingNetstandard(name))
{
return _assemblyDefinition;
return s_assemblyDefinition;
}
else
{
@@ -136,7 +136,7 @@ namespace Coverlet.Core.Instrumentation
}
}
private bool IsDotNetCore()
private static bool IsDotNetCore()
{
// object for .NET Framework is inside mscorlib.dll
return Path.GetFileName(typeof(object).Assembly.Location) == "System.Private.CoreLib.dll";
@@ -202,7 +202,7 @@ namespace Coverlet.Core.Instrumentation
catch (Exception ex)
{
// if we don't find a lib go on
_logger.LogVerbose($"TryWithCustomResolverOnDotNetCore exception: {ex.ToString()}");
_logger.LogVerbose($"TryWithCustomResolverOnDotNetCore exception: {ex}");
}
}
}
@@ -218,8 +218,8 @@ namespace Coverlet.Core.Instrumentation
internal class AspNetCoreSharedFrameworkResolver : ICompilationAssemblyResolver
{
private readonly string[] _aspNetSharedFrameworkDirs = null;
private readonly ILogger _logger = null;
private readonly string[] _aspNetSharedFrameworkDirs;
private readonly ILogger _logger;
public AspNetCoreSharedFrameworkResolver(ILogger logger)
{
@@ -49,7 +49,7 @@ namespace Coverlet.Core.Instrumentation
private readonly string[] _doesNotReturnAttributes;
private ReachabilityHelper _reachabilityHelper;
public bool SkipModule { get; set; } = false;
public bool SkipModule { get; set; }
public Instrumenter(
string module,
@@ -185,9 +185,8 @@ namespace Coverlet.Core.Instrumentation
// locking issues if we do it while writing.
private void CreateReachabilityHelper()
{
using (Stream stream = _fileSystem.NewFileStream(_module, FileMode.Open, FileAccess.Read))
using (var resolver = new NetstandardAwareAssemblyResolver(_module, _logger))
{
using Stream stream = _fileSystem.NewFileStream(_module, FileMode.Open, FileAccess.Read);
using var resolver = new NetstandardAwareAssemblyResolver(_module, _logger);
resolver.AddSearchDirectory(Path.GetDirectoryName(_module));
var parameters = new ReaderParameters { ReadSymbols = true, AssemblyResolver = resolver };
if (_isCoreLibrary)
@@ -195,20 +194,16 @@ namespace Coverlet.Core.Instrumentation
parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider();
}
using (var module = ModuleDefinition.ReadModule(stream, parameters))
{
using var module = ModuleDefinition.ReadModule(stream, parameters);
_reachabilityHelper = ReachabilityHelper.CreateForModule(module, _doesNotReturnAttributes, _logger);
}
}
}
private void InstrumentModule()
{
CreateReachabilityHelper();
using (Stream stream = _fileSystem.NewFileStream(_module, FileMode.Open, FileAccess.ReadWrite))
using (var resolver = new NetstandardAwareAssemblyResolver(_module, _logger))
{
using Stream stream = _fileSystem.NewFileStream(_module, FileMode.Open, FileAccess.ReadWrite);
using var resolver = new NetstandardAwareAssemblyResolver(_module, _logger);
resolver.AddSearchDirectory(Path.GetDirectoryName(_module));
var parameters = new ReaderParameters { ReadSymbols = true, AssemblyResolver = resolver };
if (_isCoreLibrary)
@@ -216,8 +211,7 @@ namespace Coverlet.Core.Instrumentation
parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider();
}
using (var module = ModuleDefinition.ReadModule(stream, parameters))
{
using var module = ModuleDefinition.ReadModule(stream, parameters);
foreach (CustomAttribute customAttribute in module.Assembly.CustomAttributes)
{
if (IsExcludeAttribute(customAttribute))
@@ -336,8 +330,6 @@ namespace Coverlet.Core.Instrumentation
module.Write(stream, new WriterParameters { WriteSymbols = true });
}
}
}
private void AddCustomModuleTrackerToModule(ModuleDefinition module)
{
@@ -864,52 +856,52 @@ namespace Coverlet.Core.Instrumentation
private class CoreLibMetadataImporter : IMetadataImporter
{
private readonly ModuleDefinition module;
private readonly DefaultMetadataImporter defaultMetadataImporter;
private readonly ModuleDefinition _module;
private readonly DefaultMetadataImporter _defaultMetadataImporter;
public CoreLibMetadataImporter(ModuleDefinition module)
{
this.module = module;
defaultMetadataImporter = new DefaultMetadataImporter(module);
_module = module;
_defaultMetadataImporter = new DefaultMetadataImporter(module);
}
public AssemblyNameReference ImportReference(AssemblyNameReference reference)
{
return defaultMetadataImporter.ImportReference(reference);
return _defaultMetadataImporter.ImportReference(reference);
}
public TypeReference ImportReference(TypeReference type, IGenericParameterProvider context)
{
TypeReference importedRef = defaultMetadataImporter.ImportReference(type, context);
importedRef.GetElementType().Scope = module.TypeSystem.CoreLibrary;
TypeReference importedRef = _defaultMetadataImporter.ImportReference(type, context);
importedRef.GetElementType().Scope = _module.TypeSystem.CoreLibrary;
return importedRef;
}
public FieldReference ImportReference(FieldReference field, IGenericParameterProvider context)
{
FieldReference importedRef = defaultMetadataImporter.ImportReference(field, context);
importedRef.FieldType.GetElementType().Scope = module.TypeSystem.CoreLibrary;
FieldReference importedRef = _defaultMetadataImporter.ImportReference(field, context);
importedRef.FieldType.GetElementType().Scope = _module.TypeSystem.CoreLibrary;
return importedRef;
}
public MethodReference ImportReference(MethodReference method, IGenericParameterProvider context)
{
MethodReference importedRef = defaultMetadataImporter.ImportReference(method, context);
importedRef.DeclaringType.GetElementType().Scope = module.TypeSystem.CoreLibrary;
MethodReference importedRef = _defaultMetadataImporter.ImportReference(method, context);
importedRef.DeclaringType.GetElementType().Scope = _module.TypeSystem.CoreLibrary;
foreach (ParameterDefinition parameter in importedRef.Parameters)
{
if (parameter.ParameterType.Scope == module.TypeSystem.CoreLibrary)
if (parameter.ParameterType.Scope == _module.TypeSystem.CoreLibrary)
{
continue;
}
parameter.ParameterType.GetElementType().Scope = module.TypeSystem.CoreLibrary;
parameter.ParameterType.GetElementType().Scope = _module.TypeSystem.CoreLibrary;
}
if (importedRef.ReturnType.Scope != module.TypeSystem.CoreLibrary)
if (importedRef.ReturnType.Scope != _module.TypeSystem.CoreLibrary)
{
importedRef.ReturnType.GetElementType().Scope = module.TypeSystem.CoreLibrary;
importedRef.ReturnType.GetElementType().Scope = _module.TypeSystem.CoreLibrary;
}
return importedRef;
@@ -26,8 +26,8 @@ namespace Coverlet.Core.Instrumentation
public static int[] HitsArray;
public static bool SingleHit;
public static bool FlushHitFile;
private static readonly bool _enableLog = int.TryParse(Environment.GetEnvironmentVariable("COVERLET_ENABLETRACKERLOG"), out int result) ? result == 1 : false;
private static readonly string _sessionId = Guid.NewGuid().ToString();
private static readonly bool s_enableLog = int.TryParse(Environment.GetEnvironmentVariable("COVERLET_ENABLETRACKERLOG"), out int result) && result == 1;
private static readonly string s_sessionId = Guid.NewGuid().ToString();
static ModuleTrackerTemplate()
{
@@ -83,8 +83,7 @@ namespace Coverlet.Core.Instrumentation
{
// The same module can be unloaded multiple times in the same process via different app domains.
// Use a global mutex to ensure no concurrent access.
using (var mutex = new Mutex(true, Path.GetFileNameWithoutExtension(HitsFilePath) + "_Mutex", out bool createdNew))
{
using var mutex = new Mutex(true, Path.GetFileNameWithoutExtension(HitsFilePath) + "_Mutex", out bool createdNew);
if (!createdNew)
{
mutex.WaitOne();
@@ -103,16 +102,14 @@ namespace Coverlet.Core.Instrumentation
bool failedToCreateNewHitsFile = false;
try
{
using (var fs = new FileStream(HitsFilePath, FileMode.CreateNew))
using (var bw = new BinaryWriter(fs))
{
using var fs = new FileStream(HitsFilePath, FileMode.CreateNew);
using var bw = new BinaryWriter(fs);
bw.Write(hitsArray.Length);
foreach (int hitCount in hitsArray)
{
bw.Write(hitCount);
}
}
}
catch (Exception ex)
{
WriteLog($"Failed to create new hits file '{HitsFilePath}' -> '{ex.Message}'");
@@ -123,10 +120,9 @@ namespace Coverlet.Core.Instrumentation
{
// Update the number of hits by adding value on disk with the ones on memory.
// This path should be triggered only in the case of multiple AppDomain unloads.
using (var fs = new FileStream(HitsFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
using (var br = new BinaryReader(fs))
using (var bw = new BinaryWriter(fs))
{
using var fs = new FileStream(HitsFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
using var br = new BinaryReader(fs);
using var bw = new BinaryWriter(fs);
int hitsLength = br.ReadInt32();
WriteLog($"Current hits found '{hitsLength}'");
@@ -149,7 +145,6 @@ namespace Coverlet.Core.Instrumentation
}
}
}
}
WriteHits(sender);
@@ -167,16 +162,15 @@ namespace Coverlet.Core.Instrumentation
// this case is relevant when instrumenting corelib since multiple processes can be running against the same instrumented dll.
mutex.ReleaseMutex();
}
}
private static void WriteHits(object sender)
{
if (_enableLog)
if (s_enableLog)
{
var currentAssembly = Assembly.GetExecutingAssembly();
var location = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(currentAssembly.Location), "TrackersHitsLog"));
location.Create();
string logFile = Path.Combine(location.FullName, $"{Path.GetFileName(currentAssembly.Location)}_{DateTime.UtcNow.Ticks}_{_sessionId}.txt");
string logFile = Path.Combine(location.FullName, $"{Path.GetFileName(currentAssembly.Location)}_{DateTime.UtcNow.Ticks}_{s_sessionId}.txt");
using (var fs = new FileStream(HitsFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
using (var log = new FileStream(logFile, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
using (var logWriter = new StreamWriter(log))
@@ -195,12 +189,12 @@ namespace Coverlet.Core.Instrumentation
private static void WriteLog(string logText)
{
if (_enableLog)
if (s_enableLog)
{
// We don't set path as global var to keep benign possible errors inside try/catch
// I'm not sure that location will be ok in every scenario
string location = Assembly.GetExecutingAssembly().Location;
File.AppendAllText(Path.Combine(Path.GetDirectoryName(location), Path.GetFileName(location) + "_tracker.txt"), $"[{DateTime.UtcNow} S:{_sessionId} T:{Thread.CurrentThread.ManagedThreadId}]{logText}{Environment.NewLine}");
File.AppendAllText(Path.Combine(Path.GetDirectoryName(location), Path.GetFileName(location) + "_tracker.txt"), $"[{DateTime.UtcNow} S:{s_sessionId} T:{Thread.CurrentThread.ManagedThreadId}]{logText}{Environment.NewLine}");
}
}
}
@@ -100,9 +100,9 @@ namespace Coverlet.Core.Instrumentation.Reachability
/// <summary>
/// Returns true if this branch has multiple targets.
/// </summary>
public bool HasMultiTargets => _TargetOffset == -1;
public bool HasMultiTargets => _targetOffset == -1;
private readonly int _TargetOffset;
private readonly int _targetOffset;
/// <summary>
/// Target of the branch, assuming it has a single target.
@@ -118,11 +118,11 @@ namespace Coverlet.Core.Instrumentation.Reachability
throw new InvalidOperationException($"{HasMultiTargets} is true");
}
return _TargetOffset;
return _targetOffset;
}
}
private readonly ImmutableArray<int> _TargetOffsets;
private readonly ImmutableArray<int> _targetOffsets;
/// <summary>
/// Targets of the branch, assuming it has multiple targets.
@@ -138,15 +138,15 @@ namespace Coverlet.Core.Instrumentation.Reachability
throw new InvalidOperationException($"{HasMultiTargets} is false");
}
return _TargetOffsets;
return _targetOffsets;
}
}
public BranchInstruction(int offset, int targetOffset)
{
Offset = offset;
_TargetOffset = targetOffset;
_TargetOffsets = ImmutableArray<int>.Empty;
_targetOffset = targetOffset;
_targetOffsets = ImmutableArray<int>.Empty;
}
public BranchInstruction(int offset, ImmutableArray<int> targetOffset)
@@ -157,8 +157,8 @@ namespace Coverlet.Core.Instrumentation.Reachability
}
Offset = offset;
_TargetOffset = -1;
_TargetOffsets = targetOffset;
_targetOffset = -1;
_targetOffsets = targetOffset;
}
public override string ToString()
@@ -169,7 +169,7 @@ namespace Coverlet.Core.Instrumentation.Reachability
/// OpCodes that transfer control code, even if they do not
/// introduce branch points.
/// </summary>
private static readonly ImmutableHashSet<OpCode> BRANCH_OPCODES =
private static readonly ImmutableHashSet<OpCode> s_branchOpCodes =
ImmutableHashSet.CreateRange(
new[]
{
@@ -224,7 +224,7 @@ namespace Coverlet.Core.Instrumentation.Reachability
/// OpCodes that unconditionally transfer control, so there
/// is not "fall through" branch target.
/// </summary>
private static readonly ImmutableHashSet<OpCode> UNCONDITIONAL_BRANCH_OPCODES =
private static readonly ImmutableHashSet<OpCode> s_unconditionalBranchOpCodes =
ImmutableHashSet.CreateRange(
new[]
{
@@ -235,11 +235,11 @@ namespace Coverlet.Core.Instrumentation.Reachability
}
);
private readonly ImmutableHashSet<MetadataToken> DoesNotReturnMethods;
private readonly ImmutableHashSet<MetadataToken> _doesNotReturnMethods;
private ReachabilityHelper(ImmutableHashSet<MetadataToken> doesNotReturnMethods)
{
DoesNotReturnMethods = doesNotReturnMethods;
_doesNotReturnMethods = doesNotReturnMethods;
}
/// <summary>
@@ -372,7 +372,7 @@ namespace Coverlet.Core.Instrumentation.Reachability
}
// no known methods that do not return, so everything is reachable by definition
if (DoesNotReturnMethods.IsEmpty)
if (_doesNotReturnMethods.IsEmpty)
{
return ImmutableArray<UnreachableRange>.Empty;
}
@@ -406,7 +406,7 @@ namespace Coverlet.Core.Instrumentation.Reachability
{
containsDoesNotReturnCall = containsDoesNotReturnCall || DoesNotReturn(i);
if (BRANCH_OPCODES.Contains(i.OpCode))
if (s_branchOpCodes.Contains(i.OpCode))
{
(int? singleTargetOffset, ImmutableArray<int> multiTargetOffsets) = GetInstructionTargets(i, exceptionHandlers);
@@ -453,7 +453,7 @@ namespace Coverlet.Core.Instrumentation.Reachability
{
// it's any of the B.*(_S)? or Leave(_S)? instructions
if (UNCONDITIONAL_BRANCH_OPCODES.Contains(i.OpCode))
if (s_unconditionalBranchOpCodes.Contains(i.OpCode))
{
multiTargetOffsets = ImmutableArray<int>.Empty;
singleTargetOffset = targetInstr.Offset;
@@ -527,7 +527,7 @@ namespace Coverlet.Core.Instrumentation.Reachability
/// <summary>
/// Calculates which ranges of IL are unreachable, given blocks which have head and tail reachability calculated.
/// </summary>
private ImmutableArray<UnreachableRange> DetermineUnreachableRanges(ImmutableArray<BasicBlock> blocks, int lastInstructionOffset)
private static ImmutableArray<UnreachableRange> DetermineUnreachableRanges(ImmutableArray<BasicBlock> blocks, int lastInstructionOffset)
{
ImmutableArray<UnreachableRange>.Builder ret = ImmutableArray.CreateBuilder<UnreachableRange>();
@@ -580,7 +580,7 @@ namespace Coverlet.Core.Instrumentation.Reachability
///
/// "Tail reachability" will have already been determined in CreateBlocks.
/// </summary>
private void DetermineHeadReachability(ImmutableArray<BasicBlock> blocks)
private static void DetermineHeadReachability(ImmutableArray<BasicBlock> blocks)
{
var blockLookup = blocks.ToImmutableDictionary(b => b.StartOffset);
@@ -791,7 +791,7 @@ namespace Coverlet.Core.Instrumentation.Reachability
return false;
}
return DoesNotReturnMethods.Contains(mtd.MetadataToken);
return _doesNotReturnMethods.Contains(mtd.MetadataToken);
}
/// <summary>
@@ -1,4 +1,4 @@
// Copyright (c) Toni Solarin-Sodara
// Copyright (c) Toni Solarin-Sodara
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
@@ -111,7 +111,7 @@ namespace Coverlet.Core.Reporters
{
var condition = new XElement("condition");
condition.Add(new XAttribute("number", entry.Key));
condition.Add(new XAttribute("type", entry.Value.Count() > 2 ? "switch" : "jump")); // Just guessing here
condition.Add(new XAttribute("type", entry.Value.Count > 2 ? "switch" : "jump")); // Just guessing here
condition.Add(new XAttribute("coverage", $"{summary.CalculateBranchCoverage(entry.Value).Percent.ToString(CultureInfo.InvariantCulture)}%"));
conditions.Add(condition);
}
@@ -119,7 +119,6 @@ namespace Coverlet.Core.Reporters
line.Add(conditions);
}
lines.Add(line);
classLines.Add(line);
}
@@ -39,7 +39,7 @@ namespace Coverlet.Core.Reporters
return stringBuilder.ToString();
}
private void OutputLineCoverage(CoverageDetails coverageDetails, StringBuilder builder)
private static void OutputLineCoverage(CoverageDetails coverageDetails, StringBuilder builder)
{
// The number of covered lines
OutputTeamCityServiceMessage("CodeCoverageAbsLCovered", coverageDetails.Covered, builder);
@@ -48,7 +48,7 @@ namespace Coverlet.Core.Reporters
OutputTeamCityServiceMessage("CodeCoverageAbsLTotal", coverageDetails.Total, builder);
}
private void OutputBranchCoverage(CoverageDetails coverageDetails, StringBuilder builder)
private static void OutputBranchCoverage(CoverageDetails coverageDetails, StringBuilder builder)
{
// The number of covered branches
OutputTeamCityServiceMessage("CodeCoverageAbsBCovered", coverageDetails.Covered, builder);
@@ -57,7 +57,7 @@ namespace Coverlet.Core.Reporters
OutputTeamCityServiceMessage("CodeCoverageAbsBTotal", coverageDetails.Total, builder);
}
private void OutputMethodCoverage(CoverageDetails coverageDetails, StringBuilder builder)
private static void OutputMethodCoverage(CoverageDetails coverageDetails, StringBuilder builder)
{
// The number of covered methods
OutputTeamCityServiceMessage("CodeCoverageAbsMCovered", coverageDetails.Covered, builder);
@@ -66,7 +66,7 @@ namespace Coverlet.Core.Reporters
OutputTeamCityServiceMessage("CodeCoverageAbsMTotal", coverageDetails.Total, builder);
}
private void OutputTeamCityServiceMessage(string key, double value, StringBuilder builder)
private static void OutputTeamCityServiceMessage(string key, double value, StringBuilder builder)
{
builder.AppendLine($"##teamcity[buildStatisticValue key='{key}' value='{value.ToString("0.##", new CultureInfo("en-US"))}']");
}
+5 -11
View File
@@ -20,8 +20,8 @@ namespace Coverlet.Core.Symbols
{
private const int StepOverLineCode = 0xFEEFEE;
// Create single instance, we cannot collide because we use full method name as key
private readonly ConcurrentDictionary<string, int[]> _compilerGeneratedBranchesToExclude = new ConcurrentDictionary<string, int[]>();
private readonly ConcurrentDictionary<string, List<int>> _sequencePointOffsetToSkip = new ConcurrentDictionary<string, List<int>>();
private readonly ConcurrentDictionary<string, int[]> _compilerGeneratedBranchesToExclude = new();
private readonly ConcurrentDictionary<string, List<int>> _sequencePointOffsetToSkip = new();
// In case of nested compiler generated classes, only the root one presents the CompilerGenerated attribute.
// So let's search up to the outermost declaring type to find the attribute
@@ -83,7 +83,8 @@ namespace Coverlet.Core.Symbols
{
return false;
}
if (methodDefinition.DeclaringType.CustomAttributes.Count(ca => ca.AttributeType.FullName == typeof(CompilerGeneratedAttribute).FullName) > 0)
if (methodDefinition.DeclaringType.CustomAttributes.Any(ca => ca.AttributeType.FullName == typeof(CompilerGeneratedAttribute).FullName))
{
foreach (InterfaceImplementation implementedInterface in methodDefinition.DeclaringType.Interfaces)
{
@@ -465,7 +466,6 @@ namespace Coverlet.Core.Symbols
CheckIfExceptionThrown(instructions, instruction, currentIndex) ||
CheckThrownExceptionType(instructions, instruction, currentIndex);
// The pattern for the "should we stay in the loop or not?", which we don't
// want to skip (so we have no method to try to find it), looks like this:
//
@@ -477,7 +477,6 @@ namespace Coverlet.Core.Symbols
// the "call" and branch, but it's the same idea either way: branch
// if GetResult() returned true.
static bool CheckForAsyncEnumerator(List<Instruction> instructions, Instruction instruction, int currentIndex)
{
// We're looking for the following pattern, which checks whether a
@@ -506,7 +505,6 @@ namespace Coverlet.Core.Symbols
return false;
}
static bool CheckIfExceptionThrown(List<Instruction> instructions, Instruction instruction, int currentIndex)
{
// Here, we want to find a pattern where we're checking whether a
@@ -564,7 +562,6 @@ namespace Coverlet.Core.Symbols
return false;
}
static bool CheckThrownExceptionType(List<Instruction> instructions, Instruction instruction, int currentIndex)
{
// In this case, we're looking for a branch generated by the compiler to
@@ -617,7 +614,6 @@ namespace Coverlet.Core.Symbols
return CheckForSkipDisposal(instructions, instruction, currentIndex) ||
CheckForCleanup(instructions, instruction, currentIndex);
static bool CheckForSkipDisposal(List<Instruction> instructions, Instruction instruction, int currentIndex)
{
// The async state machine generated for an "await using" contains a branch
@@ -727,7 +723,6 @@ namespace Coverlet.Core.Symbols
return false;
}
static bool CheckForCleanup(List<Instruction> instructions, Instruction instruction, int currentIndex)
{
// The pattern we're looking for here is this:
@@ -812,7 +807,6 @@ namespace Coverlet.Core.Symbols
return CheckForStateSwitch(instructions, instruction, currentIndex) ||
DisposeCheck(instructions, instruction, currentIndex);
static bool CheckForStateSwitch(List<Instruction> instructions, Instruction instruction, int currentIndex)
{
// The pattern we're looking for here is this one:
@@ -890,7 +884,7 @@ namespace Coverlet.Core.Symbols
}
}
private bool SkipGeneratedBranchesForEnumeratorCancellationAttribute(List<Instruction> instructions, Instruction instruction)
private static bool SkipGeneratedBranchesForEnumeratorCancellationAttribute(List<Instruction> instructions, Instruction instruction)
{
// For async-enumerable methods an additional cancellation token despite the default one can be passed.
// The EnumeratorCancellation attribute marks the parameter whose value is received by GetAsyncEnumerator(CancellationToken).
@@ -152,9 +152,9 @@ namespace Coverlet.MSbuild.Tasks
if (Threshold.Contains(','))
{
IEnumerable<string> thresholdValues = Threshold.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(t => t.Trim());
if (thresholdValues.Count() != thresholdTypeFlagQueue.Count())
if (thresholdValues.Count() != thresholdTypeFlagQueue.Count)
{
throw new Exception($"Threshold type flag count ({thresholdTypeFlagQueue.Count()}) and values count ({thresholdValues.Count()}) doesn't match");
throw new Exception($"Threshold type flag count ({thresholdTypeFlagQueue.Count}) and values count ({thresholdValues.Count()}) doesn't match");
}
foreach (string threshold in thresholdValues)
@@ -112,14 +112,10 @@ namespace Coverlet.MSbuild.Tasks
CoveragePrepareResult prepareResult = coverage.PrepareModules();
InstrumenterState = new TaskItem(System.IO.Path.GetTempFileName());
using (Stream instrumentedStateFile = fileSystem.NewFileStream(InstrumenterState.ItemSpec, FileMode.Open, FileAccess.Write))
{
using (Stream serializedState = CoveragePrepareResult.Serialize(prepareResult))
{
using Stream instrumentedStateFile = fileSystem.NewFileStream(InstrumenterState.ItemSpec, FileMode.Open, FileAccess.Write);
using Stream serializedState = CoveragePrepareResult.Serialize(prepareResult);
serializedState.CopyTo(instrumentedStateFile);
}
}
}
catch (Exception ex)
{
_logger.LogError(ex);
@@ -188,14 +188,14 @@ namespace Coverlet.Collector.Tests
Assert.Equal(defaultFormat, coverletSettings.ReportFormats[0]);
}
private void CreateCoverletNodes(XmlDocument doc, XmlElement configElement, string nodeSetting, string nodeValue)
private static void CreateCoverletNodes(XmlDocument doc, XmlElement configElement, string nodeSetting, string nodeValue)
{
XmlNode node = doc.CreateNode("element", nodeSetting, string.Empty);
node.InnerText = nodeValue;
configElement.AppendChild(node);
}
private void CreateCoverletNullInnerTextNodes(XmlDocument doc, XmlElement configElement, string nodeSetting)
private static void CreateCoverletNullInnerTextNodes(XmlDocument doc, XmlElement configElement, string nodeSetting)
{
XmlNode node = doc.CreateNode("element", nodeSetting, string.Empty);
node.InnerText = null;
@@ -13,7 +13,7 @@ namespace Coverlet.Core.Tests
{
public partial class CoverageTests
{
private readonly Mock<ILogger> _mockLogger = new Mock<ILogger>();
private readonly Mock<ILogger> _mockLogger = new();
[Fact]
public void TestCoverage()
@@ -23,7 +23,7 @@ namespace Coverlet.Core.Tests
{
static class TestInstrumentationHelper
{
private static IServiceProvider _processWideContainer;
private static IServiceProvider s_processWideContainer;
/// <summary>
/// caller sample: TestInstrumentationHelper.GenerateHtmlReport(result, sourceFileFilter: @"+**\Samples\Instrumentation.cs");
@@ -64,9 +64,9 @@ namespace Coverlet.Core.Tests
{
Assert.DoesNotContain("not found for module: ", message);
});
_processWideContainer.GetRequiredService<IInstrumentationHelper>().SetLogger(logger.Object);
s_processWideContainer.GetRequiredService<IInstrumentationHelper>().SetLogger(logger.Object);
var coveragePrepareResultLoaded = CoveragePrepareResult.Deserialize(result);
var coverage = new Coverage(coveragePrepareResultLoaded, logger.Object, _processWideContainer.GetService<IInstrumentationHelper>(), new FileSystem(), new SourceRootTranslator(new Mock<ILogger>().Object, new FileSystem()));
var coverage = new Coverage(coveragePrepareResultLoaded, logger.Object, s_processWideContainer.GetService<IInstrumentationHelper>(), new FileSystem(), new SourceRootTranslator(new Mock<ILogger>().Object, new FileSystem()));
return coverage.GetCoverageResult();
}
@@ -121,7 +121,7 @@ namespace Coverlet.Core.Tests
// Instrument module
var coverage = new Coverage(newPath, parameters, new Logger(logFile),
_processWideContainer.GetService<IInstrumentationHelper>(), _processWideContainer.GetService<IFileSystem>(), _processWideContainer.GetService<ISourceRootTranslator>(), _processWideContainer.GetService<ICecilSymbolHelper>());
s_processWideContainer.GetService<IInstrumentationHelper>(), s_processWideContainer.GetService<IFileSystem>(), s_processWideContainer.GetService<ISourceRootTranslator>(), s_processWideContainer.GetService<ICecilSymbolHelper>());
CoveragePrepareResult prepareResult = coverage.PrepareModules();
Assert.Single(prepareResult.Results);
@@ -153,7 +153,7 @@ namespace Coverlet.Core.Tests
private static void SetTestContainer(string testModule = null, bool disableRestoreModules = false)
{
LazyInitializer.EnsureInitialized(ref _processWideContainer, () =>
LazyInitializer.EnsureInitialized(ref s_processWideContainer, () =>
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<IRetryHelper, CustomRetryHelper>();
@@ -291,7 +291,7 @@ namespace Coverlet.Core.Tests
public abstract class ExternalProcessExecutionTest
{
protected FunctionExecutor FunctionExecutor = new FunctionExecutor(
protected FunctionExecutor FunctionExecutor = new(
o =>
{
o.StartInfo.RedirectStandardError = true;
@@ -15,7 +15,7 @@ namespace Coverlet.Core.Helpers.Tests
public class InstrumentationHelperTests
{
private readonly InstrumentationHelper _instrumentationHelper =
new InstrumentationHelper(new ProcessExitHandler(), new RetryHelper(), new FileSystem(), new Mock<ILogger>().Object, new SourceRootTranslator(typeof(InstrumentationHelperTests).Assembly.Location, new Mock<ILogger>().Object, new FileSystem()));
new(new ProcessExitHandler(), new RetryHelper(), new FileSystem(), new Mock<ILogger>().Object, new SourceRootTranslator(typeof(InstrumentationHelperTests).Assembly.Location, new Mock<ILogger>().Object, new FileSystem()));
[Fact]
public void TestGetDependencies()
@@ -26,12 +26,12 @@ namespace Coverlet.Core.Instrumentation.Tests
{
public class InstrumenterTests : IDisposable
{
private readonly Mock<ILogger> _mockLogger = new Mock<ILogger>();
private Action disposeAction;
private readonly Mock<ILogger> _mockLogger = new();
private Action _disposeAction;
public void Dispose()
{
disposeAction?.Invoke();
_disposeAction?.Invoke();
}
[ConditionalFact]
@@ -192,9 +192,7 @@ namespace Coverlet.Core.Instrumentation.Tests
Document doc = result.Documents.Values.FirstOrDefault(d => Path.GetFileName(d.Path) == "Samples.cs");
Assert.NotNull(doc);
#pragma warning disable CS0612 // Type or member is obsolete
bool found = doc.Lines.Values.Any(l => l.Method.Equals($"System.String Coverlet.Core.Samples.Tests.{testClassName}::Method(System.String)"));
#pragma warning restore CS0612 // Type or member is obsolete
Assert.False(found, "Method decorated with with exclude attribute should be excluded");
instrumenterTest.Directory.Delete(true);
@@ -211,14 +209,10 @@ namespace Coverlet.Core.Instrumentation.Tests
Document doc = result.Documents.Values.FirstOrDefault(d => Path.GetFileName(d.Path) == "Samples.cs");
Assert.NotNull(doc);
#pragma warning disable CS0612 // Type or member is obsolete
bool getFound = doc.Lines.Values.Any(l => l.Method.Equals($"System.String Coverlet.Core.Samples.Tests.{testClassName}::get_Property()"));
#pragma warning restore CS0612 // Type or member is obsolete
Assert.False(getFound, "Property getter decorated with with exclude attribute should be excluded");
#pragma warning disable CS0612 // Type or member is obsolete
bool setFound = doc.Lines.Values.Any(l => l.Method.Equals($"System.String Coverlet.Core.Samples.Tests.{testClassName}::set_Property()"));
#pragma warning restore CS0612 // Type or member is obsolete
Assert.False(setFound, "Property setter decorated with with exclude attribute should be excluded");
instrumenterTest.Directory.Delete(true);
@@ -587,7 +581,7 @@ public class SampleClass
string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(tempDirectory);
disposeAction = () => Directory.Delete(tempDirectory, true);
_disposeAction = () => Directory.Delete(tempDirectory, true);
var partialMockFileSystem = new Mock<FileSystem>();
partialMockFileSystem.CallBase = true;
@@ -30,7 +30,7 @@ namespace Coverlet.Core.Tests.Instrumentation
public class ModuleTrackerTemplateTests : ExternalProcessExecutionTest
{
private static readonly Task<int> _success = Task.FromResult(0);
private static readonly Task<int> s_success = Task.FromResult(0);
[Fact]
public void HitsFileCorrectlyWritten()
@@ -44,7 +44,7 @@ namespace Coverlet.Core.Tests.Instrumentation
int[] expectedHitsArray = new[] { 1, 2, 0, 3 };
Assert.Equal(expectedHitsArray, ReadHitsFile());
return _success;
return s_success;
});
}
@@ -57,7 +57,7 @@ namespace Coverlet.Core.Tests.Instrumentation
WriteHitsFile(new[] { 1, 2, 3 });
ModuleTrackerTemplate.HitsArray = new[] { 1 };
Assert.Throws<InvalidOperationException>(() => ModuleTrackerTemplate.UnloadModule(null, null));
return _success;
return s_success;
});
}
@@ -94,7 +94,7 @@ namespace Coverlet.Core.Tests.Instrumentation
}
}
return _success;
return s_success;
});
}
@@ -113,7 +113,7 @@ namespace Coverlet.Core.Tests.Instrumentation
int[] expectedHitsArray = new[] { 0, 4, 4, 4 };
Assert.Equal(expectedHitsArray, ReadHitsFile());
return _success;
return s_success;
});
}
@@ -149,24 +149,21 @@ namespace Coverlet.Core.Tests.Instrumentation
}
private void WriteHitsFile(int[] hitsArray)
{
using (var fs = new FileStream(ModuleTrackerTemplate.HitsFilePath, FileMode.Create))
using (var bw = new BinaryWriter(fs))
private static void WriteHitsFile(int[] hitsArray)
{
using var fs = new FileStream(ModuleTrackerTemplate.HitsFilePath, FileMode.Create);
using var bw = new BinaryWriter(fs);
bw.Write(hitsArray.Length);
foreach (int hitCount in hitsArray)
{
bw.Write(hitCount);
}
}
}
private int[] ReadHitsFile()
{
using (var fs = new FileStream(ModuleTrackerTemplate.HitsFilePath, FileMode.Open))
using (var br = new BinaryReader(fs))
private static int[] ReadHitsFile()
{
using var fs = new FileStream(ModuleTrackerTemplate.HitsFilePath, FileMode.Open);
using var br = new BinaryReader(fs);
int[] hitsArray = new int[br.ReadInt32()];
for (int i = 0; i < hitsArray.Length; ++i)
{
@@ -176,5 +173,4 @@ namespace Coverlet.Core.Tests.Instrumentation
return hitsArray;
}
}
}
}
@@ -41,7 +41,7 @@ namespace Coverlet.Core.Symbols.Tests
// assert
Assert.NotNull(points);
Assert.Equal(2, points.Count());
Assert.Equal(2, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(0, points[0].Path);
Assert.Equal(1, points[1].Path);
@@ -61,7 +61,7 @@ namespace Coverlet.Core.Symbols.Tests
// act
System.Collections.Generic.IReadOnlyList<BranchPoint> points = _cecilSymbolHelper.GetBranchPoints(method);
Assert.Equal(2, points.Count());
Assert.Equal(2, points.Count);
}
[Fact]
@@ -89,7 +89,7 @@ namespace Coverlet.Core.Symbols.Tests
// assert
Assert.NotNull(points);
Assert.Equal(4, points.Count());
Assert.Equal(4, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(points[2].Offset, points[3].Offset);
Assert.Equal(28, points[0].StartLine);
@@ -108,7 +108,7 @@ namespace Coverlet.Core.Symbols.Tests
// assert
Assert.NotNull(points);
Assert.Equal(2, points.Count());
Assert.Equal(2, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(35, points[0].StartLine);
Assert.Equal(35, points[1].StartLine);
@@ -127,7 +127,7 @@ namespace Coverlet.Core.Symbols.Tests
// assert
Assert.NotNull(points);
Assert.Equal(4, points.Count());
Assert.Equal(4, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(points[0].Offset, points[2].Offset);
Assert.Equal(3, points[3].Path);
@@ -150,7 +150,7 @@ namespace Coverlet.Core.Symbols.Tests
// assert
Assert.NotNull(points);
Assert.Equal(4, points.Count());
Assert.Equal(4, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(points[0].Offset, points[2].Offset);
Assert.Equal(3, points[3].Path);
@@ -173,7 +173,7 @@ namespace Coverlet.Core.Symbols.Tests
// assert
Assert.NotNull(points);
Assert.Equal(4, points.Count());
Assert.Equal(4, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(points[0].Offset, points[2].Offset);
Assert.Equal(3, points[3].Path);
@@ -196,7 +196,7 @@ namespace Coverlet.Core.Symbols.Tests
// assert
Assert.NotNull(points);
Assert.Equal(4, points.Count());
Assert.Equal(4, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(points[0].Offset, points[2].Offset);
Assert.Equal(points[0].Offset, points[3].Offset);
@@ -351,7 +351,7 @@ namespace Coverlet.Core.Symbols.Tests
// We do expect there to be a two-way branch (stay in the loop or not?) on
// the line containing "await foreach".
Assert.NotNull(points);
Assert.Equal(2, points.Count());
Assert.Equal(2, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(204, points[0].StartLine);
Assert.Equal(204, points[1].StartLine);
@@ -375,7 +375,7 @@ namespace Coverlet.Core.Symbols.Tests
// containing "await foreach" and the other being the "if" statement inside
// the loop.
Assert.NotNull(points);
Assert.Equal(4, points.Count());
Assert.Equal(4, points.Count);
Assert.Equal(points[0].Offset, points[1].Offset);
Assert.Equal(points[2].Offset, points[3].Offset);
Assert.Equal(219, points[0].StartLine);
@@ -399,7 +399,7 @@ namespace Coverlet.Core.Symbols.Tests
// assert
// We do expect the "for" loop to be a branch with two branch points, but that's it.
Assert.NotNull(points);
Assert.Equal(2, points.Count());
Assert.Equal(2, points.Count);
Assert.Equal(237, points[0].StartLine);
Assert.Equal(237, points[1].StartLine);
}
+2 -2
View File
@@ -24,7 +24,7 @@ namespace Coverlet.Integration.Tests
public abstract class BaseTest
{
private static int _folderSuffix = 0;
private static int s_folderSuffix;
protected BuildConfiguration GetAssemblyBuildConfiguration()
{
@@ -67,7 +67,7 @@ namespace Coverlet.Integration.Tests
private protected ClonedTemplateProject CloneTemplateProject(bool cleanupOnDispose = true, string testSDKVersion = "16.5.0")
{
DirectoryInfo finalRoot = Directory.CreateDirectory($"{Guid.NewGuid().ToString("N").Substring(0, 6)}{Interlocked.Increment(ref _folderSuffix)}");
DirectoryInfo finalRoot = Directory.CreateDirectory($"{Guid.NewGuid().ToString("N")[..6]}{Interlocked.Increment(ref s_folderSuffix)}");
foreach (string file in (Directory.GetFiles($"../../../../coverlet.integration.template", "*.cs")
.Union(Directory.GetFiles($"../../../../coverlet.integration.template", "*.csproj")
.Union(Directory.GetFiles($"../../../../coverlet.integration.template", "nuget.config")))))