Skip to content

Commit

Permalink
Log the thread id in verbose mode (#3517)
Browse files Browse the repository at this point in the history
* Log the thread id in verbose mode

Fixes  #3515
  • Loading branch information
duncanp-sonar committed Jan 5, 2023
1 parent e16488b commit 2be0b6f
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 26 deletions.
106 changes: 83 additions & 23 deletions src/Integration.UnitTests/Helpers/SonarLintOutputTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -41,58 +42,117 @@ public void Write_OutputsToWindow()
{
// Arrange
var windowMock = new ConfigurableVsOutputWindow();
var sonarLintSettings = CreateSonarLintSettings(DaemonLogLevel.Info);
var serviceProviderMock = CreateConfiguredServiceProvider(windowMock);

var serviceProviderMock = new ConfigurableServiceProvider(assertOnUnexpectedServiceRequest: true);
serviceProviderMock.RegisterService(typeof(SVsOutputWindow), windowMock);

var logger = new SonarLintOutputLogger(serviceProviderMock, Mock.Of<ISonarLintSettings>());
var testSubject = CreateTestSubject(serviceProviderMock, sonarLintSettings);

// Act
logger.WriteLine("123");
logger.WriteLine("abc");
testSubject.WriteLine("123");
testSubject.WriteLine("abc");

// Assert
var outputPane = windowMock.AssertPaneExists(VsShellUtils.SonarLintOutputPaneGuid);
outputPane.AssertOutputStrings("123", "abc");
}

[TestMethod]
[DataRow(DaemonLogLevel.Info, false)]
[DataRow(DaemonLogLevel.Minimal, false)]
[DataRow(DaemonLogLevel.Verbose, true)]
public void LogVerbose_OutputsToWindowIfLogLevelIsVerbose(DaemonLogLevel logLevel, bool shouldLogMessage)
[DataRow(DaemonLogLevel.Info)]
[DataRow(DaemonLogLevel.Minimal)]
[DataRow(DaemonLogLevel.Verbose)]
public void LogVerbose_OnlyOutputsToWindowIfLogLevelIsVerbose(DaemonLogLevel logLevel)
{
// Arrange
var windowMock = new ConfigurableVsOutputWindow();
var serviceProviderMock = CreateConfiguredServiceProvider(windowMock);

var serviceProviderMock = new ConfigurableServiceProvider(assertOnUnexpectedServiceRequest: true);
serviceProviderMock.RegisterService(typeof(SVsOutputWindow), windowMock);

var sonarLintSettings = new Mock<ISonarLintSettings>();
sonarLintSettings.Setup(x => x.DaemonLogLevel).Returns(logLevel);

var logger = new SonarLintOutputLogger(serviceProviderMock, sonarLintSettings.Object);
var sonarLintSettings = CreateSonarLintSettings(logLevel);

logger.WriteLine("create window pane");
var testSubject = CreateTestSubject(serviceProviderMock, sonarLintSettings);

testSubject.WriteLine("create window pane");
var outputPane = windowMock.AssertPaneExists(VsShellUtils.SonarLintOutputPaneGuid);
outputPane.Reset();

// Act
logger.LogVerbose("123 {0} {1}", "param 1", 2);
logger.LogVerbose("{0} {1} abc", 1, "param 2");
testSubject.LogVerbose("123 {0} {1}", "param 1", 2);
testSubject.LogVerbose("{0} {1} abc", 1, "param 2");

// Assert

if (shouldLogMessage)
if (logLevel == DaemonLogLevel.Verbose)
{
outputPane.AssertOutputStrings("DEBUG: 123 param 1 2", "DEBUG: 1 param 2 abc");
var currentThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;

outputPane.AssertOutputStrings(
$"[ThreadId {currentThreadId}] [DEBUG] 123 param 1 2",
$"[ThreadId {currentThreadId}] [DEBUG] 1 param 2 abc");
outputPane.AssertOutputStrings(2);
}
else
{
outputPane.AssertOutputStrings(0);
}
}

[TestMethod]
[DataRow(DaemonLogLevel.Info)]
[DataRow(DaemonLogLevel.Minimal)]
[DataRow(DaemonLogLevel.Verbose)]
public void WriteLine_ThreadIdIsAddedIfLogLevelIsVerbose(DaemonLogLevel logLevel)
{
// Arrange
var windowMock = new ConfigurableVsOutputWindow();
var serviceProviderMock = CreateConfiguredServiceProvider(windowMock);

var sonarLintSettings = CreateSonarLintSettings(logLevel);

var testSubject = CreateTestSubject(serviceProviderMock, sonarLintSettings);

testSubject.WriteLine("create window pane");
var outputPane = windowMock.AssertPaneExists(VsShellUtils.SonarLintOutputPaneGuid);
outputPane.Reset();

// Act
testSubject.WriteLine("writeline, no params");
testSubject.WriteLine("writeline, with params: {0}", "zzz");

outputPane.AssertOutputStrings(2);

string expectedPrefix;
if (logLevel == DaemonLogLevel.Verbose)
{
var currentThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
expectedPrefix = $"[ThreadId {currentThreadId}] ";
}
else
{
expectedPrefix = string.Empty;
}

outputPane.AssertOutputStrings(
$"{expectedPrefix}writeline, no params",
$"{expectedPrefix}writeline, with params: zzz");
}

private static IServiceProvider CreateConfiguredServiceProvider(IVsOutputWindow outputWindow)
{
var serviceProvider = new ConfigurableServiceProvider(assertOnUnexpectedServiceRequest: true);
serviceProvider.RegisterService(typeof(SVsOutputWindow), outputWindow);
return serviceProvider;
}

private static ISonarLintSettings CreateSonarLintSettings(DaemonLogLevel logLevel)
{
var sonarLintSettings = new Mock<ISonarLintSettings>();
sonarLintSettings.Setup(x => x.DaemonLogLevel).Returns(logLevel);
return sonarLintSettings.Object;
}

private static SonarLintOutputLogger CreateTestSubject(IServiceProvider serviceProvider,
ISonarLintSettings sonarLintSettings = null)
{
sonarLintSettings ??= Mock.Of<ISonarLintSettings>();
return new SonarLintOutputLogger(serviceProvider, sonarLintSettings);
}
}
}
17 changes: 14 additions & 3 deletions src/Integration/Helpers/SonarLintOutputLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,32 @@ public SonarLintOutputLogger([Import(typeof(SVsServiceProvider))] IServiceProvid

public void WriteLine(string message)
{
VsShellUtils.WriteToSonarLintOutputPane(this.serviceProvider, message);
var prefixedMessage = AddPrefixIfVerboseLogging(message);
VsShellUtils.WriteToSonarLintOutputPane(this.serviceProvider, prefixedMessage);
}

public void WriteLine(string messageFormat, params object[] args)
{
VsShellUtils.WriteToSonarLintOutputPane(this.serviceProvider, messageFormat, args);
var prefixedMessageFormat = AddPrefixIfVerboseLogging(messageFormat);
VsShellUtils.WriteToSonarLintOutputPane(this.serviceProvider, prefixedMessageFormat, args);
}

public void LogVerbose(string messageFormat, params object[] args)
{
if (sonarLintSettings.DaemonLogLevel == DaemonLogLevel.Verbose)
{
var text = args.Length == 0 ? messageFormat : string.Format(messageFormat, args);
WriteLine("DEBUG: " + text);
WriteLine("[DEBUG] " + text);
}
}

private string AddPrefixIfVerboseLogging(string message)
{
if (sonarLintSettings.DaemonLogLevel == DaemonLogLevel.Verbose)
{
message = $"[ThreadId {System.Threading.Thread.CurrentThread.ManagedThreadId}] " + message;
}
return message;
}
}
}

0 comments on commit 2be0b6f

Please sign in to comment.