Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ladipro committed Apr 29, 2021
1 parent 9fc5b3f commit 5cfb9f6
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
88 changes: 88 additions & 0 deletions src/Build.UnitTests/BackEnd/LoggingService_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,11 @@ public void Properties()
Assert.Equal(1, loggingService.MaxCPUCount);
loggingService.MaxCPUCount = 5;
Assert.Equal(5, loggingService.MaxCPUCount);

// Test MinimumRequiredMessageImportance
Assert.Equal(MessageImportance.Low, loggingService.MinimumRequiredMessageImportance);
loggingService.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
Assert.Equal(MessageImportance.Normal, loggingService.MinimumRequiredMessageImportance);
}

#endregion
Expand Down Expand Up @@ -718,6 +723,8 @@ public void LoggingPacketReceived()

#endregion

#region WarningsAsErrors Tests

private static readonly BuildWarningEventArgs BuildWarningEventForTreatAsErrorOrMessageTests = new BuildWarningEventArgs("subcategory", "C94A41A90FFB4EF592BF98BA59BEE8AF", "file", 1, 2, 3, 4, "message", "helpKeyword", "senderName");

/// <summary>
Expand Down Expand Up @@ -1000,6 +1007,76 @@ private MockLogger GetLoggedEventsWithWarningsAsErrorsOrMessages(
return logger;
}

#endregion

#region MinimumRequiredMessageImportance Tests

[Fact]
public void ImportanceReflectsConsoleLoggerVerbosity()
{
_initializedService.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Quiet));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.High - 1);
_initializedService.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Minimal));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.High);
_initializedService.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Normal);
_initializedService.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Detailed));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Low);
_initializedService.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Diagnostic));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Low);
}

[Fact]
public void ImportanceReflectsConfigurableForwardingLoggerVerbosity()
{
_initializedService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Quiet));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.High - 1);
_initializedService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Minimal));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.High);
_initializedService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Normal));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Normal);
_initializedService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Detailed));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Low);
_initializedService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Diagnostic));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Low);
}

[Fact]
public void ImportanceReflectsCentralForwardingLoggerVerbosity()
{
MockHost mockHost = new MockHost();
ILoggingService node1LoggingService = LoggingService.CreateLoggingService(LoggerMode.Synchronous, 1);
((IBuildComponent)node1LoggingService).InitializeComponent(mockHost);
ILoggingService node2LoggingService = LoggingService.CreateLoggingService(LoggerMode.Synchronous, 2);
((IBuildComponent)node2LoggingService).InitializeComponent(mockHost);

// CentralForwardingLogger is always registered in in-proc nodes and it does not affect minimum importance.
node1LoggingService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Minimal));
node1LoggingService.RegisterLogger(new CentralForwardingLogger());
node1LoggingService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.High);

// CentralForwardingLogger in out-of-proc nodes means that we are forwarding everything and the minimum importance
// is Low regardless of what other loggers are registered.
node2LoggingService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Minimal));
node2LoggingService.RegisterLogger(new CentralForwardingLogger());
node2LoggingService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Low);
// Register another ConsoleLogger and verify that minimum importance hasn't changed.
node2LoggingService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Minimal));
node2LoggingService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Low);
}

[Fact]
public void ImportanceReflectsUnknownLoggerVerbosity()
{
// Minimum message importance is Low (i.e. we're logging everything) even when all registered loggers have
// Normal verbosity if at least of one them is not on our whitelist.
_initializedService.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
_initializedService.RegisterLogger(new MockLogger() { Verbosity = LoggerVerbosity.Normal });
_initializedService.RegisterLogger(CreateConfigurableForwardingLogger(LoggerVerbosity.Normal));
_initializedService.MinimumRequiredMessageImportance.ShouldBe(MessageImportance.Low);
}
#endregion

#region PrivateMethods

/// <summary>
Expand Down Expand Up @@ -1084,6 +1161,17 @@ private LoggerDescription CreateLoggerDescription(string loggerClassName, string
);
return centralLoggerDescrption;
}

/// <summary>
/// Creates a new <see cref="ConfigurableForwardingLogger"/> with the given verbosity.
/// </summary>
private ConfigurableForwardingLogger CreateConfigurableForwardingLogger(LoggerVerbosity verbosity)
{
return new ConfigurableForwardingLogger()
{
Verbosity = verbosity
};
}
#endregion

#region HelperClasses
Expand Down
62 changes: 62 additions & 0 deletions src/MSBuild.UnitTests/XMake_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Shouldly;
using System.IO.Compression;
using System.Reflection;
using Microsoft.Build.Utilities;

namespace Microsoft.Build.UnitTests
{
Expand Down Expand Up @@ -2335,6 +2336,67 @@ public void EndToEndWarnAsErrors()
success.ShouldBeFalse();
}

/// <summary>
/// Helper task used by <see cref="EndToEndMinimumMessageImportance"/> to verify <see cref="TaskLoggingHelper.ShouldLogMessage"/>.
/// </summary>
public class MessageImportanceCheckingTask : Task
{
public int ExpectedMinimumMessageImportance { get; set; }

public override bool Execute()
{
bool shouldLogHigh = Log.ShouldLogMessage(MessageImportance.High);
bool shouldLogNormal = Log.ShouldLogMessage(MessageImportance.Normal);
bool shouldLogLow = Log.ShouldLogMessage(MessageImportance.Low);
return (MessageImportance)ExpectedMinimumMessageImportance switch
{
MessageImportance.High - 1 => !shouldLogHigh && !shouldLogNormal && !shouldLogLow,
MessageImportance.High => shouldLogHigh && !shouldLogNormal && !shouldLogLow,
MessageImportance.Normal => shouldLogHigh && shouldLogNormal && !shouldLogLow,
MessageImportance.Low => shouldLogHigh && shouldLogNormal && shouldLogLow,
_ => false
};
}
}

[Theory]
[InlineData("/v:diagnostic", MessageImportance.Low)]
[InlineData("/v:detailed", MessageImportance.Low)]
[InlineData("/v:normal", MessageImportance.Normal)]
[InlineData("/v:minimal", MessageImportance.High)]
[InlineData("/v:quiet", MessageImportance.High - 1)]
[InlineData("/v:diagnostic /bl", MessageImportance.Low)]
[InlineData("/v:detailed /bl", MessageImportance.Low)]
[InlineData("/v:normal /bl", MessageImportance.Low)] // v:normal but with binary logger so everything must be logged
[InlineData("/v:minimal /bl", MessageImportance.Low)] // v:minimal but with binary logger so everything must be logged
[InlineData("/v:quiet /bl", MessageImportance.Low)] // v:quiet but with binary logger so everything must be logged
public void EndToEndMinimumMessageImportance(string arguments, MessageImportance expectedMinimumMessageImportance)
{
using TestEnvironment testEnvironment = UnitTests.TestEnvironment.Create();

string projectContents = ObjectModelHelpers.CleanupFileContents(@"<Project>
<UsingTask TaskName=""" + typeof(MessageImportanceCheckingTask).FullName + @""" AssemblyFile=""" + Assembly.GetExecutingAssembly().Location + @"""/>
<Target Name=""CheckMessageImportance"">
<MessageImportanceCheckingTask ExpectedMinimumMessageImportance=""" + (int)expectedMinimumMessageImportance + @""" />
</Target>
</Project>");

TransientTestProjectWithFiles testProject = testEnvironment.CreateTestProjectWithFiles(projectContents);

// Build in-proc.
RunnerUtilities.ExecMSBuild($"{arguments} \"{testProject.ProjectFile}\"", out bool success, _output);
success.ShouldBeTrue();

// Build out-of-proc to exercise both logging code paths.
testEnvironment.SetEnvironmentVariable("MSBUILDNOINPROCNODE", "1");
testEnvironment.SetEnvironmentVariable("MSBUILDDISABLENODEREUSE", "1");
RunnerUtilities.ExecMSBuild($"{arguments} \"{testProject.ProjectFile}\"", out success, _output);
success.ShouldBeTrue();
}

#if FEATURE_ASSEMBLYLOADCONTEXT
/// <summary>
/// Ensure that tasks get loaded into their own <see cref="System.Runtime.Loader.AssemblyLoadContext"/>
Expand Down

0 comments on commit 5cfb9f6

Please sign in to comment.