Skip to content
This repository was archived by the owner on Nov 15, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 92 additions & 60 deletions main/OpenCover.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ namespace OpenCover.Console
{
class Program
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(Bootstrapper));

/// <summary>
/// This is the initial console harness - it may become the full thing
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
static int Main(string[] args)
{

var returnCode = 0;
int returnCode;
var returnCodeOffset = 0;
var logger = LogManager.GetLogger(typeof (Bootstrapper));

try
{
CommandLineParser parser;
Expand All @@ -43,86 +44,80 @@ static int Main(string[] args)

returnCodeOffset = parser.ReturnCodeOffset;
var filter = BuildFilter(parser);
var perfCounter = CreatePerformanceCounter(parser);

string outputFile;
if (!GetFullOutputFile(parser, out outputFile)) return returnCodeOffset + 1;

IPerfCounters perfCounter = new NullPerfCounter();
if (parser.EnablePerformanceCounters)
using (var container = new Bootstrapper(Logger))
{
if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
{
perfCounter = new PerfCounters();
}
else
{
throw new InvalidCredentialException("You must be running as an Administrator to enable performance counters.");
}
var persistance = new FilePersistance(parser, Logger);
container.Initialise(filter, parser, persistance, perfCounter);
persistance.Initialise(outputFile, parser.MergeExistingOutputFile);
returnCode = RunWithContainer(parser, container, persistance);
}

using (var container = new Bootstrapper(logger))
perfCounter.ResetCounters();
}
catch (Exception ex)
{
if (Logger.IsFatalEnabled)
{
var persistance = new FilePersistance(parser, logger);
container.Initialise(filter, parser, persistance, perfCounter);
persistance.Initialise(outputFile, parser.MergeExistingOutputFile);
var registered = false;
Logger.FatalFormat("An exception occured: {0}", ex.Message);
Logger.FatalFormat("stack: {0}", ex.StackTrace);
}

try
{
if (parser.Register)
{
ProfilerRegistration.Register(parser.Registration);
registered = true;
}
returnCode = returnCodeOffset + 1;
}

var harness = container.Resolve<IProfilerManager>();
return returnCode;
}

var servicePrincipal =
(parser.Service
? new[] { ServiceEnvironmentManagement.MachineQualifiedServiceAccountName(parser.Target) }
: new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();
private static int RunWithContainer(CommandLineParser parser, Bootstrapper container, IPersistance persistance)
{
var returnCode = 0;
var registered = false;

harness.RunProcess(environment =>
{
returnCode = 0;
if (parser.Service)
{
RunService(parser, environment, logger);
}
else
{
returnCode = RunProcess(parser, environment);
}
}, servicePrincipal);
try
{
if (parser.Register)
{
ProfilerRegistration.Register(parser.Registration);
registered = true;
}

DisplayResults(persistance, parser, logger);
var harness = container.Resolve<IProfilerManager>();

}
catch (Exception ex)
var servicePrincipal =
(parser.Service
? new[] {ServiceEnvironmentManagement.MachineQualifiedServiceAccountName(parser.Target)}
: new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();

harness.RunProcess(environment =>
{
if (parser.Service)
{
Trace.WriteLine(string.Format("Exception: {0}\n{1}", ex.Message, ex.InnerException));
throw;
RunService(parser, environment, Logger);
returnCode = 0;
}
finally
else
{
if (parser.Register && registered)
ProfilerRegistration.Unregister(parser.Registration);
returnCode = RunProcess(parser, environment);
}
}
}, servicePrincipal);

perfCounter.ResetCounters();
DisplayResults(persistance, parser, Logger);
}
catch (Exception ex)
{
if (logger.IsFatalEnabled)
{
logger.FatalFormat("An exception occured: {0}", ex.Message);
logger.FatalFormat("stack: {0}", ex.StackTrace);
}

returnCode = returnCodeOffset + 1;
Trace.WriteLine(string.Format("Exception: {0}\n{1}", ex.Message, ex.InnerException));
throw;
}
finally
{
if (parser.Register && registered)
ProfilerRegistration.Unregister(parser.Registration);
}

return returnCode;
}

Expand Down Expand Up @@ -458,6 +453,27 @@ private static IFilter BuildFilter(CommandLineParser parser)
return filter;
}

private static IPerfCounters CreatePerformanceCounter(CommandLineParser parser)
{
if (parser.EnablePerformanceCounters)
{
if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
{
return new PerfCounters();
}
else
{
throw new InvalidCredentialException(
"You must be running as an Administrator to enable performance counters.");
}
}
else
{
return new NullPerfCounter();
}
}


private static bool ParseCommandLine(string[] args, out CommandLineParser parser)
{
try
Expand All @@ -480,6 +496,22 @@ private static bool ParseCommandLine(string[] args, out CommandLineParser parser
return false;
}


if (parser.PrintVersion)
{
var entryAssembly = System.Reflection.Assembly.GetEntryAssembly();
if (entryAssembly == null)
{
Logger.Warn("No entry assembly, running from unmanaged application");
}
else
{
var version = entryAssembly.GetName().Version;
System.Console.WriteLine("OpenCover version {0}", version);
return false;
}
}

if (!string.IsNullOrWhiteSpace(parser.TargetDir) && !Directory.Exists(parser.TargetDir))
{
System.Console.WriteLine("TargetDir '{0}' cannot be found - have you specified your arguments correctly?", parser.TargetDir);
Expand Down
31 changes: 24 additions & 7 deletions main/OpenCover.Framework/CommandLineParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public CommandLineParser(string[] arguments)
ServiceEnvironment = ServiceEnvironment.None;
RegExFilters = false;
Registration = Registration.Normal;
PrintVersion = false;
}

/// <summary>
Expand Down Expand Up @@ -117,9 +118,11 @@ public string Usage()
builder.AppendLine(" [-oldStyle]");
builder.AppendLine("or");
builder.AppendLine(" -?");
builder.AppendLine("or");
builder.AppendLine(" -version");
builder.AppendLine("");
builder.AppendLine("For further information on the command line please visit the wiki");
builder.AppendLine(" https://github.com/sawilde/opencover/wiki/Usage");
builder.AppendLine(" https://github.com/OpenCover/opencover/wiki/Usage");
builder.AppendLine("");
builder.AppendLine("Filters:");
builder.AppendLine(" Filters are used to include and exclude assemblies and types in the");
Expand Down Expand Up @@ -234,17 +237,15 @@ public void ExtractAndValidateArguments()
case "?":
PrintUsage = true;
break;
case "version":
PrintVersion = true;
break;
default:
throw new InvalidOperationException(string.Format("The argument {0} is not recognised", key));
}
}

if (PrintUsage) return;

if (string.IsNullOrWhiteSpace(Target))
{
throw new InvalidOperationException("The target argument is required");
}
ValidateArguments();
}

private T ExtractValue<T>(string argumentName, Action onError)
Expand Down Expand Up @@ -304,6 +305,17 @@ private static List<SkippedMethod> ExtractSkipped(string skipped)
return list.Distinct().ToList();
}

private void ValidateArguments()
{
if (PrintUsage || PrintVersion) return;

if (string.IsNullOrWhiteSpace(Target))
{
throw new InvalidOperationException("The target argument is required");
}
}


/// <summary>
/// the switch -register was supplied
/// </summary>
Expand Down Expand Up @@ -444,6 +456,11 @@ private static List<SkippedMethod> ExtractSkipped(string skipped)
/// If an existing output exists then load it and allow merging of test runs
/// </summary>
public bool MergeExistingOutputFile { get; private set; }

/// <summary>
/// Instructs the console to print its version and exit
/// </summary>
public bool PrintVersion { get; private set; }
}

}
29 changes: 28 additions & 1 deletion main/OpenCover.Test/Framework/CommandLineParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void ParserHasKnownDefaultArguments()
Assert.IsFalse(parser.TraceByTest);
Assert.IsFalse(parser.SkipAutoImplementedProperties);
Assert.IsFalse(parser.RegExFilters);

Assert.IsFalse(parser.PrintVersion);
}

[Test]
Expand Down Expand Up @@ -673,5 +673,32 @@ public void HandlesMergeOutputArgument()
// assert
Assert.IsTrue(parser.MergeExistingOutputFile);
}

[Test]
public void HandlesVersionArgument()
{
// arrange
var parser = new CommandLineParser(new[] {"-version"});

// act
parser.ExtractAndValidateArguments();

// assert
Assert.IsTrue(parser.PrintVersion);
}

[Test]
public void NoArguments_ThrowException()
{
// arrange
var parser = new CommandLineParser(new string[0]);

// act
var thrownException = Assert.Throws<InvalidOperationException>(parser.ExtractAndValidateArguments);

// assert
Assert.That(thrownException.Message, Contains.Substring("target"));
Assert.That(thrownException.Message, Contains.Substring("required"));
}
}
}