Skip to content

Commit

Permalink
Add ThrowIfOnUIThread to SLCoreServiceProvider (#5243)
Browse files Browse the repository at this point in the history
  • Loading branch information
georgii-borovinskikh-sonarsource authored Feb 22, 2024
1 parent e593fa9 commit 9ccf396
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
20 changes: 17 additions & 3 deletions src/SLCore.UnitTests/Core/SLCoreServiceProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ public class SLCoreServiceProviderTests
public void MefCtor_CheckIsExported()
{
MefTestHelpers.CheckTypeCanBeImported<SLCoreServiceProvider, ISLCoreServiceProvider>(
MefTestHelpers.CreateExport<IThreadHandling>(),
MefTestHelpers.CreateExport<ILogger>());
}

[TestMethod]
public void MefCtor_WriterInterface_CheckIsExported()
{
MefTestHelpers.CheckTypeCanBeImported<SLCoreServiceProvider, ISLCoreServiceProviderWriter>(
MefTestHelpers.CreateExport<IThreadHandling>(),
MefTestHelpers.CreateExport<ILogger>());
}

Expand All @@ -57,6 +59,17 @@ public void TryGetTransientService_TypeNotInterface_Throws()

act.Should().Throw<ArgumentException>().WithMessage($"The type argument {typeof(TestSLCoreService).FullName} is not an interface");
}

[TestMethod]
public void TryGetTransientService_NotUIThread_Checked()
{
var threadHandling = new Mock<IThreadHandling>();
var testSubject = CreateTestSubject(threadHandling:threadHandling.Object);

testSubject.TryGetTransientService(out ITestSLcoreService1 _);

threadHandling.Verify(x => x.ThrowIfOnUIThread());
}

[TestMethod]
public void TryGetTransientService_NotInitialized_ReturnsFalse()
Expand Down Expand Up @@ -86,7 +99,7 @@ public void TryGetTransientService_RpcThrows_LoggedAndReturnsFalse()

var logger = new TestLogger();

var testSubject = CreateTestSubject(rpcMock.Object, logger);
var testSubject = CreateTestSubject(rpcMock.Object, logger:logger);

var result = testSubject.TryGetTransientService(out ISLCoreService service);

Expand Down Expand Up @@ -196,10 +209,11 @@ private static void SetUpConnectionState(Mock<ISLCoreJsonRpc> rpcMock, bool isAl
rpcMock.SetupGet(x => x.IsAlive).Returns(isAlive);
}

private SLCoreServiceProvider CreateTestSubject(ISLCoreJsonRpc jsonRpc = null, ILogger logger = null)
private SLCoreServiceProvider CreateTestSubject(ISLCoreJsonRpc jsonRpc = null, IThreadHandling threadHandling = null, ILogger logger = null)
{
threadHandling ??= new NoOpThreadHandler();
logger ??= new TestLogger();
var testSubject = new SLCoreServiceProvider(logger);
var testSubject = new SLCoreServiceProvider(threadHandling, logger);
if (jsonRpc != null)
{
testSubject.SetCurrentConnection(jsonRpc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using SonarLint.VisualStudio.Infrastructure.VS;
using SonarLint.VisualStudio.SLCore.Common.Models;
using SonarLint.VisualStudio.SLCore.Core;
using SonarLint.VisualStudio.SLCore.Listener;
Expand Down Expand Up @@ -52,7 +53,7 @@ public async Task SLCore_InitializeStandaloneAndShutdown()
var slCoreRunner = new SLCoreRunner(slcoreBat, enableVerboseLogs: true);
var logger = new TestLogger();

var slCoreServiceProvider = new SLCoreServiceProvider(logger);
var slCoreServiceProvider = new SLCoreServiceProvider(new NoOpThreadHandler(), logger);
slCoreServiceProvider.SetCurrentConnection(slCoreRunner.Rpc);
var slCoreListenerSetUp = new SLCoreListenerSetUp(new[] { new LoggerListener(new TestLogger(logToConsole: true)) });
slCoreListenerSetUp.Setup(slCoreRunner.Rpc);
Expand Down
7 changes: 6 additions & 1 deletion src/SLCore/Core/ISLCoreServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,24 @@ public interface ISLCoreServiceProviderWriter
[PartCreationPolicy(CreationPolicy.Shared)]
public class SLCoreServiceProvider : ISLCoreServiceProvider, ISLCoreServiceProviderWriter
{

private readonly Dictionary<Type, object> cache = new Dictionary<Type, object>();
private readonly object cacheLock = new object();
private ISLCoreJsonRpc jsonRpc;
private readonly IThreadHandling threadHandling;
private readonly ILogger logger;

[ImportingConstructor]
public SLCoreServiceProvider(ILogger logger)
public SLCoreServiceProvider(IThreadHandling threadHandling, ILogger logger)
{
this.threadHandling = threadHandling;
this.logger = logger;
}

public bool TryGetTransientService<TService>(out TService service) where TService : class, ISLCoreService
{
threadHandling.ThrowIfOnUIThread();

service = default;

var serviceType = typeof(TService);
Expand Down

0 comments on commit 9ccf396

Please sign in to comment.