Skip to content

Commit

Permalink
[WIP] Add integration test to test all of our MEF exports
Browse files Browse the repository at this point in the history
- partial. The basic test infrastructure works, but there are dozens of types that cannot be imported
because lots of our MEF constructors fetch services and perform work (see SonarSource#4512)

Relates to SonarSource#4825
  • Loading branch information
duncanp-sonar committed Sep 29, 2023
1 parent 15a2e88 commit ea57ff9
Show file tree
Hide file tree
Showing 7 changed files with 2,147 additions and 0 deletions.
10 changes: 10 additions & 0 deletions SonarLint.VisualStudio.Integration.sln
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VsAnalyzerConfig", "VsAnaly
src\vs-threading.MainThreadAssertingMethods.txt = src\vs-threading.MainThreadAssertingMethods.txt
src\vs-threading.MainThreadSwitchingMethods.txt = src\vs-threading.MainThreadSwitchingMethods.txt
EndProjectSection
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Integration.Vsix.IntegrationTests", "src\Integration.Vsix.IntegrationTests\Integration.Vsix.IntegrationTests.csproj", "{B5C573DA-E568-48E1-AD6E-643DC4844688}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -496,6 +497,14 @@ Global
{4F5AE2A8-56DD-44EC-9872-B7884CC1C1DB}.Release|Any CPU.Build.0 = Release|Any CPU
{4F5AE2A8-56DD-44EC-9872-B7884CC1C1DB}.Release|x86.ActiveCfg = Release|Any CPU
{4F5AE2A8-56DD-44EC-9872-B7884CC1C1DB}.Release|x86.Build.0 = Release|Any CPU
{B5C573DA-E568-48E1-AD6E-643DC4844688}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5C573DA-E568-48E1-AD6E-643DC4844688}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5C573DA-E568-48E1-AD6E-643DC4844688}.Debug|x86.ActiveCfg = Debug|Any CPU
{B5C573DA-E568-48E1-AD6E-643DC4844688}.Debug|x86.Build.0 = Debug|Any CPU
{B5C573DA-E568-48E1-AD6E-643DC4844688}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5C573DA-E568-48E1-AD6E-643DC4844688}.Release|Any CPU.Build.0 = Release|Any CPU
{B5C573DA-E568-48E1-AD6E-643DC4844688}.Release|x86.ActiveCfg = Release|Any CPU
{B5C573DA-E568-48E1-AD6E-643DC4844688}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -546,6 +555,7 @@ Global
{EE7F939B-7127-433C-80CD-5DB278361229} = {32F0945C-72D0-4116-95D5-F9EE2177D51B}
{4F5AE2A8-56DD-44EC-9872-B7884CC1C1DB} = {32F0945C-72D0-4116-95D5-F9EE2177D51B}
{682C440B-E506-4811-9569-9734D8DF4620} = {A4C88C9A-7C47-47FE-8AB6-8D7588D05EF1}
{B5C573DA-E568-48E1-AD6E-643DC4844688} = {41145B06-4EAD-4B9E-B1ED-C5B98AC55932}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DABC27C8-E761-4826-AD2D-056F677EF3C0}
Expand Down
50 changes: 50 additions & 0 deletions src/Integration.Vsix.IntegrationTests/Helpers/DeferredLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-2023 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
using System.Collections.Generic;

namespace SonarLint.VisualStudio.Integration.Vsix.IntegrationTests.Helpers;

/// <summary>
/// Helper class that allows a test to control whether an output message is
/// logged immediately, or deferred until the test has ended and the logger is disposed
/// </summary>
/// <remarks>
/// The test output window in VS only shows a limited number of lines, so if a test produces
/// a lot of output if can be tedious to find the important information e.g. the reason for
/// a test failure.
/// This class allows less important information to be logged when the test ends so the most
/// useful information appears in the test output first.
///
/// * LogImmediate - write directly to the test output console i.e. will appear at the top
/// * LogDeferred - use for detailed information that will appear at the end of the log
///</remarks>
internal class DeferredLogger : IDisposable
{
private List<string> deferredLogMessages = new List<string>();
public void LogDeferred(string? message = null) => deferredLogMessages.Add(message);
public void LogImmediate(string message = null) => Console.WriteLine(message);

public void Dispose()
{
foreach (var message in deferredLogMessages) { Console.WriteLine(message); }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\SonarLint.Test.props" />

<PropertyGroup Label="Specify which VS-specific refs are required">
<RequiresTeamFoundation>true</RequiresTeamFoundation>
</PropertyGroup>
<Import Project="..\SonarLint.VSSpecificAssemblies.props" />

<PropertyGroup>
<ProjectGuid>{B5C573DA-E568-48E1-AD6E-643DC4844688}</ProjectGuid>
<RootNamespace>SonarLint.VisualStudio.Integration.Vsix.IntegrationTests</RootNamespace>
<AssemblyName>SonarLint.VisualStudio.Integration.Vsix.IntegrationTests</AssemblyName>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.3.1" />
</ItemGroup>

<ItemGroup Label="Framework references">
<Reference Include="System.ComponentModel.Composition" />
</ItemGroup>

<PropertyGroup>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Integration.Vsix\Integration.Vsix.csproj" />
<ProjectReference Include="..\TestInfrastructure\TestInfrastructure.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-2023 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Moq;

namespace SonarLint.VisualStudio.Integration.Vsix.IntegrationTests.MEF;

// Our classes import a number of types exported by VS. We don't want to load the real
// VS implementations (we're not running in VS so it would probably fail), but we need
// to provide a suitable dummy export otherwise the composition will fail.

[Export(typeof(SVsServiceProvider))]
internal class DummySVsServiceProvider : SVsServiceProvider
{
private readonly IVsSolution solution = Mock.Of<IVsSolution>();

public object GetService(Type serviceType)
{
// TODO: our MEF constructors should not be calling serviceProvider.GetService
// during construction, but many of them do (see #4512). SVsSolution is one of the most
// requested services - returning a mock here prevents multiple exceptions when
// running the test.
if (serviceType == typeof(SVsSolution))
{
return solution;
}
return null;
}
}
Loading

0 comments on commit ea57ff9

Please sign in to comment.