Skip to content
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

Added logging to Coverage to help with debugging #341

Merged
merged 18 commits into from
Feb 27, 2019
Merged
Show file tree
Hide file tree
Changes from 16 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
48 changes: 24 additions & 24 deletions src/coverlet.console/Logging/ConsoleLogger.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
using System;
using Coverlet.Core.Logging;
using static System.Console;

namespace Coverlet.Console.Logging
{
class ConsoleLogger : ILogger
{
public void LogError(string message)
{
ForegroundColor = ConsoleColor.Red;
WriteLine(message);
ForegroundColor = ConsoleColor.White;
}
private static readonly object _sync = new object();

public void LogInformation(string message)
{
WriteLine(message);
}
public void LogError(string message) => Log(message, ConsoleColor.Red);

public void LogSuccess(string message)
{
ForegroundColor = ConsoleColor.Green;
WriteLine(message);
ForegroundColor = ConsoleColor.White;
}
public void LogError(Exception exception) => LogError(exception.ToString());

public void LogVerbose(string message)
{
throw new System.NotImplementedException();
}
public void LogInformation(string message) => Log(message, ForegroundColor);

public void LogVerbose(string message) => throw new NotImplementedException();

public void LogWarning(string message) => Log(message, ConsoleColor.Yellow);

public void LogWarning(string message)
private void Log(string message, ConsoleColor color)
{
ForegroundColor = ConsoleColor.Yellow;
WriteLine(message);
ForegroundColor = ConsoleColor.White;
lock (_sync)
{
ConsoleColor currentForegroundColor;
if (color != (currentForegroundColor = ForegroundColor))
{
ForegroundColor = color;
WriteLine(message);
ForegroundColor = currentForegroundColor;
}
else
{
WriteLine(message);
}
}
}
}
}
21 changes: 18 additions & 3 deletions src/coverlet.console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using ConsoleTables;
using Coverlet.Console.Logging;
using Coverlet.Core;
Expand Down Expand Up @@ -49,7 +50,7 @@ static int Main(string[] args)
if (!target.HasValue())
throw new CommandParsingException(app, "Target must be specified.");

Coverage coverage = new Coverage(module.Value, includeFilters.Values.ToArray(), includeDirectories.Values.ToArray(), excludeFilters.Values.ToArray(), excludedSourceFiles.Values.ToArray(), excludeAttributes.Values.ToArray(), singleHit.HasValue(), mergeWith.Value(), useSourceLink.HasValue());
Coverage coverage = new Coverage(module.Value, includeFilters.Values.ToArray(), includeDirectories.Values.ToArray(), excludeFilters.Values.ToArray(), excludedSourceFiles.Values.ToArray(), excludeAttributes.Values.ToArray(), singleHit.HasValue(), mergeWith.Value(), useSourceLink.HasValue(), logger);
coverage.PrepareModules();

Process process = new Process();
Expand All @@ -58,9 +59,23 @@ static int Main(string[] args)
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.OutputDataReceived += (sender, eventArgs) =>
{
if(!string.IsNullOrEmpty(eventArgs.Data))
logger.LogInformation(eventArgs.Data);
};

process.ErrorDataReceived += (sender, eventArgs) =>
{
if (!string.IsNullOrEmpty(eventArgs.Data))
logger.LogError(eventArgs.Data);
};

process.Start();
logger.LogInformation(process.StandardOutput.ReadToEnd());
logger.LogError(process.StandardError.ReadToEnd());

process.BeginErrorReadLine();
process.BeginOutputReadLine();

MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved
process.WaitForExit();

var dOutput = output.HasValue() ? output.Value() : Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar.ToString();
Expand Down
20 changes: 15 additions & 5 deletions src/coverlet.core/Coverage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
using System.IO;
using System.Linq;

using Coverlet.Core.Enums;
using Coverlet.Core.Helpers;
using Coverlet.Core.Instrumentation;
using Coverlet.Core.Symbols;
using Coverlet.Core.Logging;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
Expand All @@ -25,14 +24,24 @@ public class Coverage
private bool _singleHit;
private string _mergeWith;
private bool _useSourceLink;
private ILogger _logger;
private List<InstrumenterResult> _results;

public string Identifier
{
get { return _identifier; }
}

public Coverage(string module, string[] includeFilters, string[] includeDirectories, string[] excludeFilters, string[] excludedSourceFiles, string[] excludeAttributes, bool singleHit, string mergeWith, bool useSourceLink)
public Coverage(string module,
string[] includeFilters,
string[] includeDirectories,
string[] excludeFilters,
string[] excludedSourceFiles,
string[] excludeAttributes,
bool singleHit,
string mergeWith,
bool useSourceLink,
ILogger logger)
{
_module = module;
_includeFilters = includeFilters;
Expand All @@ -43,6 +52,7 @@ public Coverage(string module, string[] includeFilters, string[] includeDirector
_singleHit = singleHit;
_mergeWith = mergeWith;
_useSourceLink = useSourceLink;
_logger = logger;

_identifier = Guid.NewGuid().ToString();
_results = new List<InstrumenterResult>();
Expand Down Expand Up @@ -72,9 +82,9 @@ public void PrepareModules()
var result = instrumenter.Instrument();
_results.Add(result);
}
catch (Exception)
catch (Exception ex)
{
// TODO: With verbose logging we should note that instrumentation failed.
_logger.LogWarning($"Unable to instrument module: {module} because : {ex.Message}");
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved
InstrumentationHelper.RestoreOriginalModule(module, _identifier);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
namespace Coverlet.Console.Logging
using System;

namespace Coverlet.Core.Logging
{
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved
interface ILogger
public interface ILogger
{
void LogSuccess(string message);
void LogVerbose(string message);
void LogInformation(string message);
void LogWarning(string message);
void LogError(string message);
void LogError(Exception exception);
}
}
17 changes: 11 additions & 6 deletions src/coverlet.msbuild.tasks/CoverageResultTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class CoverageResultTask : Task
private double _threshold;
private string _thresholdType;
private string _thresholdStat;
private MSBuildLogger _logger;

[Required]
public string Output
Expand Down Expand Up @@ -54,11 +55,16 @@ public string ThresholdStat
set { _thresholdStat = value; }
}

public CoverageResultTask()
{
_logger = new MSBuildLogger(Log);
}

public override bool Execute()
{
try
{
Console.WriteLine("\nCalculating coverage result...");
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved
Console.WriteLine("Calculating coverage result...");

var coverage = InstrumentationTask.Coverage;
var result = coverage.GetCoverageResult();
Expand All @@ -85,7 +91,7 @@ public override bool Execute()
if (reporter.OutputType == ReporterOutputType.Console)
{
// Output to console
Console.WriteLine(" Outputting results to console");
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved
Console.WriteLine("Outputting results to console");
Console.WriteLine(reporter.Report(result));
}
else
Expand All @@ -96,7 +102,7 @@ public override bool Execute()
filename = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

var report = Path.Combine(directory, filename);
Console.WriteLine($" Generating report '{report}'");
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved
Console.WriteLine($"Generating report '{report}'");
File.WriteAllText(report, reporter.Report(result));
}
}
Expand Down Expand Up @@ -146,7 +152,6 @@ public override bool Execute()
coverageTable.AddRow(Path.GetFileNameWithoutExtension(module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
}

Console.WriteLine();
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved
Console.WriteLine(coverageTable.ToStringAlternative());

coverageTable.Columns.Clear();
Expand All @@ -155,7 +160,7 @@ public override bool Execute()
coverageTable.AddColumn(new [] { "", "Line", "Branch", "Method"});
coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
coverageTable.AddRow("Average", $"{totalLinePercent / numModules}%", $"{totalBranchPercent / numModules}%", $"{totalMethodPercent / numModules}%");

Console.WriteLine(coverageTable.ToStringAlternative());

thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, _threshold, thresholdTypeFlags, thresholdStat);
Expand All @@ -182,7 +187,7 @@ public override bool Execute()
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
_logger.LogError(ex);
return false;
}

Expand Down
10 changes: 8 additions & 2 deletions src/coverlet.msbuild.tasks/InstrumentationTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class InstrumentationTask : Task
private bool _singleHit;
private string _mergeWith;
private bool _useSourceLink;
private readonly MSBuildLogger _logger;
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved

internal static Coverage Coverage
{
Expand Down Expand Up @@ -78,6 +79,11 @@ public bool UseSourceLink
set { _useSourceLink = value; }
}

public InstrumentationTask()
{
_logger = new MSBuildLogger(Log);
}

public override bool Execute()
{
try
Expand All @@ -88,12 +94,12 @@ public override bool Execute()
var excludedSourceFiles = _excludeByFile?.Split(',');
var excludeAttributes = _excludeByAttribute?.Split(',');

_coverage = new Coverage(_path, includeFilters, includeDirectories, excludeFilters, excludedSourceFiles, excludeAttributes, _singleHit, _mergeWith, _useSourceLink);
_coverage = new Coverage(_path, includeFilters, includeDirectories, excludeFilters, excludedSourceFiles, excludeAttributes, _singleHit, _mergeWith, _useSourceLink, _logger);
_coverage.PrepareModules();
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
_logger.LogError(ex);
return false;
}

Expand Down
25 changes: 25 additions & 0 deletions src/coverlet.msbuild.tasks/MSBuildLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using ILogger = Coverlet.Core.Logging.ILogger;

namespace Coverlet.MSbuild.Tasks
{
class MSBuildLogger : ILogger
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved
{
private readonly TaskLoggingHelper _log;

public MSBuildLogger(TaskLoggingHelper log) => _log = log;

public void LogVerbose(string message) => _log.LogMessage(MessageImportance.Low, message);

// We use `MessageImportance.High` because with `MessageImportance.Normal` doesn't show anything
public void LogInformation(string message)=> _log.LogMessage(MessageImportance.High, message);
MarcoRossignoli marked this conversation as resolved.
Show resolved Hide resolved

public void LogWarning(string message) => _log.LogWarning(message);

public void LogError(string message) => _log.LogError(message);

public void LogError(Exception exception) => _log.LogErrorFromException(exception);
}
}
8 changes: 4 additions & 4 deletions test/coverlet.core.tests/CoverageTests.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using System;
using System.IO;

using Coverlet.Core.Logging;
using Xunit;
using Moq;

using Coverlet.Core;
using System.Collections.Generic;

namespace Coverlet.Core.Tests
{
Expand All @@ -22,9 +20,11 @@ public void TestCoverage()
File.Copy(module, Path.Combine(directory.FullName, Path.GetFileName(module)), true);
File.Copy(pdb, Path.Combine(directory.FullName, Path.GetFileName(pdb)), true);

var logger = Mock.Of<ILogger>();

// TODO: Find a way to mimick hits

var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), false, string.Empty, false);
var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), false, string.Empty, false, logger);
coverage.PrepareModules();

var result = coverage.GetCoverageResult();
Expand Down