* Re-enable IntegrationTests

* Try new images

* Use scout build

* Re-direct for VS.LS.Protocol

* Upgrade VS.Ext.Testing version

* Register all Handlers

* Include all Handlers

* Fix autoinsert test

* Cleanup

* Remove extra wrapper class

* CodeBase for MS.VS.LS.P

* Fix some failures

* Skip CodeFolding tests for now

* Turn off VS What's new for Integration tests

* Make edit to force project.json rewrite

* PR feedback

* Cleanup

* Use better file-close api

* Skip SetBreakpoint_FirstCharacter_SpanAdjusts

* React to logging changes

* Allow 2 attempts

* Cleanup
This commit is contained in:
Ryan Brandenburg 2022-10-11 14:58:39 -07:00 коммит произвёл GitHub
Родитель 22ee8f48c8
Коммит 7107ae895b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
15 изменённых файлов: 134 добавлений и 26 удалений

Просмотреть файл

@ -27,6 +27,8 @@ resources:
variables: variables:
- name: XUNIT_LOGS - name: XUNIT_LOGS
value: $(Build.SourcesDirectory)\artifacts\log\$(_configuration) value: $(Build.SourcesDirectory)\artifacts\log\$(_configuration)
- name: __VSNeverShowWhatsNew
value: 1
stages: stages:
- template: \stages\visual-studio\agent.yml@DartLabTemplates - template: \stages\visual-studio\agent.yml@DartLabTemplates

Просмотреть файл

@ -111,7 +111,7 @@ stages:
pool: pool:
${{ if eq(variables['System.TeamProject'], 'public') }}: ${{ if eq(variables['System.TeamProject'], 'public') }}:
name: NetCore-Public name: NetCore-Public
demands: ImageOverride -equals windows.vs2022preview.amd64.open demands: ImageOverride -equals windows.vs2022preview.scout.amd64.open
${{ if ne(variables['System.TeamProject'], 'public') }}: ${{ if ne(variables['System.TeamProject'], 'public') }}:
name: NetCore1ESPool-Internal name: NetCore1ESPool-Internal
demands: ImageOverride -equals windows.vs2022preview.amd64 demands: ImageOverride -equals windows.vs2022preview.amd64
@ -141,10 +141,11 @@ stages:
/p:DotNetPublishBlobFeedUrl=$(_PublishBlobFeedUrl) /p:DotNetPublishBlobFeedUrl=$(_PublishBlobFeedUrl)
/p:DotNetPublishToBlobFeed=$(_DotNetPublishToBlobFeed) /p:DotNetPublishToBlobFeed=$(_DotNetPublishToBlobFeed)
variables: variables:
- _DotNetPublishToBlobFeed : false - _DotNetPublishToBlobFeed: false
- _PublishBlobFeedUrl: https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore-tooling/index.json - _PublishBlobFeedUrl: https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore-tooling/index.json
- _BuildArgs: '' - _BuildArgs: ''
- XUNIT_LOGS: '$(Build.SourcesDirectory)\artifacts\log\$(_BuildConfig)' - XUNIT_LOGS: '$(Build.SourcesDirectory)\artifacts\log\$(_BuildConfig)'
- __VSNeverShowWhatsNew: 1
# Variables for internal Official builds # Variables for internal Official builds
- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
@ -241,8 +242,8 @@ stages:
-configuration $(_BuildConfig) -configuration $(_BuildConfig)
-prepareMachine -prepareMachine
-test -test
# -integrationTest -integrationTest
# /p:BuildProjectReferences=false /p:BuildProjectReferences=false
name: Run_Tests name: Run_Tests
displayName: Run Unit and Integration tests displayName: Run Unit and Integration tests
condition: succeeded() condition: succeeded()

Просмотреть файл

@ -97,7 +97,7 @@
<MicrosoftCodeAnalysisAnalyzerTestingPackageVersion>$(Tooling_MicrosoftCodeAnalysisTestingVersion)</MicrosoftCodeAnalysisAnalyzerTestingPackageVersion> <MicrosoftCodeAnalysisAnalyzerTestingPackageVersion>$(Tooling_MicrosoftCodeAnalysisTestingVersion)</MicrosoftCodeAnalysisAnalyzerTestingPackageVersion>
<MicrosoftCodeAnalysisTestingVerifiersXunitPackageVersion>$(Tooling_MicrosoftCodeAnalysisTestingVersion)</MicrosoftCodeAnalysisTestingVerifiersXunitPackageVersion> <MicrosoftCodeAnalysisTestingVerifiersXunitPackageVersion>$(Tooling_MicrosoftCodeAnalysisTestingVersion)</MicrosoftCodeAnalysisTestingVerifiersXunitPackageVersion>
<MicrosoftVisualStudioEditorPackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioEditorPackageVersion> <MicrosoftVisualStudioEditorPackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioEditorPackageVersion>
<MicrosoftVisualStudioExtensibilityTestingXunitVersion>0.1.145-beta</MicrosoftVisualStudioExtensibilityTestingXunitVersion> <MicrosoftVisualStudioExtensibilityTestingXunitVersion>0.1.149-beta</MicrosoftVisualStudioExtensibilityTestingXunitVersion>
<MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>$(MicrosoftVisualStudioExtensibilityTestingXunitVersion)</MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion> <MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>$(MicrosoftVisualStudioExtensibilityTestingXunitVersion)</MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>
<MicrosoftVisualStudioLanguagePackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioLanguagePackageVersion> <MicrosoftVisualStudioLanguagePackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioLanguagePackageVersion>
<MicrosoftVisualStudioLanguageIntellisensePackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioLanguageIntellisensePackageVersion> <MicrosoftVisualStudioLanguageIntellisensePackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioLanguageIntellisensePackageVersion>

Просмотреть файл

@ -30,10 +30,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.DocumentHighlighting
public RegistrationExtensionResult GetRegistration(VSInternalClientCapabilities clientCapabilities) public RegistrationExtensionResult GetRegistration(VSInternalClientCapabilities clientCapabilities)
{ {
const string ServerCapability = "documentHighlightProvider"; const string ServerCapability = "documentHighlightProvider";
var options = new DocumentHighlightOptions var options = new SumType<bool, DocumentHighlightOptions>(
{ new DocumentHighlightOptions
WorkDoneProgress = false {
}; WorkDoneProgress = false
});
return new RegistrationExtensionResult(ServerCapability, options); return new RegistrationExtensionResult(ServerCapability, options);
} }

Просмотреть файл

@ -20,7 +20,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Folding
{ {
internal class FoldingRangeEndpoint : IVSFoldingRangeEndpoint internal class FoldingRangeEndpoint : IVSFoldingRangeEndpoint
{ {
private readonly DocumentContextFactory _documentContextFactory;
private readonly RazorDocumentMappingService _documentMappingService; private readonly RazorDocumentMappingService _documentMappingService;
private readonly ClientNotifierServiceBase _languageServer; private readonly ClientNotifierServiceBase _languageServer;
private readonly IEnumerable<RazorFoldingRangeProvider> _foldingRangeProviders; private readonly IEnumerable<RazorFoldingRangeProvider> _foldingRangeProviders;
@ -29,13 +28,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Folding
public bool MutatesSolutionState => false; public bool MutatesSolutionState => false;
public FoldingRangeEndpoint( public FoldingRangeEndpoint(
DocumentContextFactory documentContextFactory,
RazorDocumentMappingService documentMappingService, RazorDocumentMappingService documentMappingService,
ClientNotifierServiceBase languageServer, ClientNotifierServiceBase languageServer,
IEnumerable<RazorFoldingRangeProvider> foldingRangeProviders, IEnumerable<RazorFoldingRangeProvider> foldingRangeProviders,
ILoggerFactory loggerFactory) ILoggerFactory loggerFactory)
{ {
_documentContextFactory = documentContextFactory ?? throw new ArgumentNullException(nameof(documentContextFactory));
_documentMappingService = documentMappingService ?? throw new ArgumentNullException(nameof(documentMappingService)); _documentMappingService = documentMappingService ?? throw new ArgumentNullException(nameof(documentMappingService));
_languageServer = languageServer ?? throw new ArgumentNullException(nameof(languageServer)); _languageServer = languageServer ?? throw new ArgumentNullException(nameof(languageServer));
_foldingRangeProviders = foldingRangeProviders ?? throw new ArgumentNullException(nameof(foldingRangeProviders)); _foldingRangeProviders = foldingRangeProviders ?? throw new ArgumentNullException(nameof(foldingRangeProviders));
@ -60,7 +57,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Folding
{ {
using var _ = _logger.BeginScope("FoldingRangeEndpoint.Handle"); using var _ = _logger.BeginScope("FoldingRangeEndpoint.Handle");
var documentContext = await _documentContextFactory.TryCreateAsync(@params.TextDocument.Uri, cancellationToken).ConfigureAwait(false); var documentContext = requestContext.DocumentContext;
if (documentContext is null) if (documentContext is null)
{ {
return null; return null;

Просмотреть файл

@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Implementation
public RegistrationExtensionResult GetRegistration(VSInternalClientCapabilities clientCapabilities) public RegistrationExtensionResult GetRegistration(VSInternalClientCapabilities clientCapabilities)
{ {
const string ServerCapability = "implementationProvider"; const string ServerCapability = "implementationProvider";
var option = new ImplementationOptions(); var option = new SumType<bool, ImplementationOptions>(new ImplementationOptions());
return new RegistrationExtensionResult(ServerCapability, option); return new RegistrationExtensionResult(ServerCapability, option);
} }

Просмотреть файл

@ -9,11 +9,14 @@ using Microsoft.AspNetCore.Razor.LanguageServer.Debugging;
using Microsoft.AspNetCore.Razor.LanguageServer.Definition; using Microsoft.AspNetCore.Razor.LanguageServer.Definition;
using Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics; using Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics;
using Microsoft.AspNetCore.Razor.LanguageServer.DocumentColor; using Microsoft.AspNetCore.Razor.LanguageServer.DocumentColor;
using Microsoft.AspNetCore.Razor.LanguageServer.DocumentHighlighting;
using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts; using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts;
using Microsoft.AspNetCore.Razor.LanguageServer.Extensions; using Microsoft.AspNetCore.Razor.LanguageServer.Extensions;
using Microsoft.AspNetCore.Razor.LanguageServer.Folding; using Microsoft.AspNetCore.Razor.LanguageServer.Folding;
using Microsoft.AspNetCore.Razor.LanguageServer.Implementation;
using Microsoft.AspNetCore.Razor.LanguageServer.LinkedEditingRange; using Microsoft.AspNetCore.Razor.LanguageServer.LinkedEditingRange;
using Microsoft.AspNetCore.Razor.LanguageServer.Refactoring; using Microsoft.AspNetCore.Razor.LanguageServer.Refactoring;
using Microsoft.AspNetCore.Razor.LanguageServer.SignatureHelp;
using Microsoft.AspNetCore.Razor.LanguageServer.Telemetry; using Microsoft.AspNetCore.Razor.LanguageServer.Telemetry;
using Microsoft.AspNetCore.Razor.LanguageServer.WrapWithTag; using Microsoft.AspNetCore.Razor.LanguageServer.WrapWithTag;
using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor;
@ -34,6 +37,8 @@ internal class RazorLanguageServer : AbstractLanguageServer<RazorRequestContext>
private readonly LanguageServerFeatureOptions? _featureOptions; private readonly LanguageServerFeatureOptions? _featureOptions;
private readonly ProjectSnapshotManagerDispatcher? _projectSnapshotManagerDispatcher; private readonly ProjectSnapshotManagerDispatcher? _projectSnapshotManagerDispatcher;
private readonly Action<IServiceCollection>? _configureServer; private readonly Action<IServiceCollection>? _configureServer;
// Cached for testing
private IHandlerProvider? _handlerProvider;
public RazorLanguageServer( public RazorLanguageServer(
JsonRpc jsonRpc, JsonRpc jsonRpc,
@ -134,6 +139,9 @@ internal class RazorLanguageServer : AbstractLanguageServer<RazorRequestContext>
static void AddHandlers(IServiceCollection services) static void AddHandlers(IServiceCollection services)
{ {
services.AddRegisteringHandler<ImplementationEndpoint>();
services.AddRegisteringHandler<SignatureHelpEndpoint>();
services.AddRegisteringHandler<DocumentHighlightEndpoint>();
services.AddHandler<RazorDiagnosticsEndpoint>(); services.AddHandler<RazorDiagnosticsEndpoint>();
services.AddHandler<RazorConfigurationEndpoint>(); services.AddHandler<RazorConfigurationEndpoint>();
services.AddRegisteringHandler<OnAutoInsertEndpoint>(); services.AddRegisteringHandler<OnAutoInsertEndpoint>();
@ -150,10 +158,38 @@ internal class RazorLanguageServer : AbstractLanguageServer<RazorRequestContext>
} }
} }
protected override IHandlerProvider GetHandlerProvider()
{
_handlerProvider ??= base.GetHandlerProvider();
return _handlerProvider;
}
internal T GetRequiredService<T>() where T : notnull internal T GetRequiredService<T>() where T : notnull
{ {
var lspServices = GetLspServices(); var lspServices = GetLspServices();
return lspServices.GetRequiredService<T>(); return lspServices.GetRequiredService<T>();
} }
// Internal for testing
internal TestAccessor GetTestAccessor()
{
return new TestAccessor(this);
}
internal class TestAccessor
{
private RazorLanguageServer _server;
public TestAccessor(RazorLanguageServer server)
{
_server = server;
}
public IHandlerProvider GetHandlerProvider()
{
return _server.GetHandlerProvider();
}
}
} }

Просмотреть файл

@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
public async Task ExitAsync() public async Task ExitAsync()
{ {
await _languageServer.ExitAsync(); await _languageServer.ExitAsync();
_tcs.SetResult(0); _tcs.TrySetResult(0);
} }
public async Task ShutdownAsync(string message = "Shutting down") public async Task ShutdownAsync(string message = "Shutting down")

Просмотреть файл

@ -658,7 +658,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
csharpTask = Task.Run(async () => csharpTask = Task.Run(async () =>
{ {
var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync( var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync(
foldingRangeParams.HostDocumentVersion, csharpDocument, cancellationToken); foldingRangeParams.HostDocumentVersion, csharpDocument, cancellationToken);
if (synchronized) if (synchronized)
{ {
@ -695,7 +695,7 @@ namespace Microsoft.VisualStudio.LanguageServerClient.Razor
htmlTask = Task.Run(async () => htmlTask = Task.Run(async () =>
{ {
var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync( var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync(
foldingRangeParams.HostDocumentVersion, htmlDocument, cancellationToken); foldingRangeParams.HostDocumentVersion, htmlDocument, cancellationToken);
if (synchronized) if (synchronized)
{ {

Просмотреть файл

@ -0,0 +1,66 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Test.Common;
using Microsoft.CommonLanguageServerProtocol.Framework;
using Nerdbank.Streams;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Test;
public class RazorLanguageServerTest : TestBase
{
public RazorLanguageServerTest(ITestOutputHelper testOutput)
: base(testOutput)
{
}
[Fact]
public async Task AllHandlersRegisteredAsync()
{
var (clientStream, serverStream) = FullDuplexStream.CreatePair();
await using var server = RazorLanguageServerWrapper.Create(serverStream, serverStream, Logger);
var innerServer = server.GetInnerLanguageServerForTesting();
var handlerProvider = innerServer.GetTestAccessor().GetHandlerProvider();
var registeredMethods = handlerProvider.GetRegisteredMethods();
var handlerTypes = typeof(RazorLanguageServerWrapper).Assembly.GetTypes()
.Where(t => typeof(IMethodHandler).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface);
if (registeredMethods.Length != handlerTypes.Count())
{
var unregisteredHandlers = handlerTypes.Where(t => !registeredMethods.Any(m => m.MethodName == GetMethodFromType(t)));
Assert.True(false, $"Unregistered handlers: {string.Join(";", unregisteredHandlers.Select(t => t.Name))}");
}
static string GetMethodFromType(Type t)
{
var attribute = t.GetCustomAttribute<LanguageServerEndpointAttribute>();
if (attribute is null)
{
foreach (var inter in t.GetInterfaces())
{
attribute = inter.GetCustomAttribute<LanguageServerEndpointAttribute>();
if (attribute is not null)
{
break;
}
}
}
if (attribute is null)
{
throw new NotImplementedException();
}
return attribute.Method;
}
}
}

Просмотреть файл

@ -25,7 +25,7 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
/// <item><description><see cref="IDisposable.Dispose"/></description></item> /// <item><description><see cref="IDisposable.Dispose"/></description></item>
/// </list> /// </list>
/// </remarks> /// </remarks>
[IdeSettings(MinVersion = VisualStudioVersion.VS2022, RootSuffix = "RoslynDev")] [IdeSettings(MinVersion = VisualStudioVersion.VS2022, RootSuffix = "RoslynDev", MaxAttempts = 2)]
public abstract class AbstractIntegrationTest : AbstractIdeIntegrationTest public abstract class AbstractIntegrationTest : AbstractIdeIntegrationTest
{ {
protected const string ProjectName = "TestProj"; protected const string ProjectName = "TestProj";

Просмотреть файл

@ -49,6 +49,7 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
await EnsureExtensionInstalledAsync(ControlledHangMitigatingCancellationToken); await EnsureExtensionInstalledAsync(ControlledHangMitigatingCancellationToken);
EnsureMEFCompositionSuccessForRazor(); EnsureMEFCompositionSuccessForRazor();
await TestServices.Editor.PlaceCaretAsync("</PageTitle>", charsOffset: 1, ControlledHangMitigatingCancellationToken);
await TestServices.Editor.WaitForComponentClassificationAsync(ControlledHangMitigatingCancellationToken, count: 3); await TestServices.Editor.WaitForComponentClassificationAsync(ControlledHangMitigatingCancellationToken, count: 3);
// Close the file we opened, just in case, so the test can start with a clean slate // Close the file we opened, just in case, so the test can start with a clean slate

Просмотреть файл

@ -121,7 +121,7 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
} }
} }
[IdeFact] [IdeFact(Skip = "https://github.com/dotnet/razor-tooling/issues/6966")]
public async Task CodeFolding_CodeBlock() public async Task CodeFolding_CodeBlock()
{ {
await TestServices.SolutionExplorer.AddFileAsync( await TestServices.SolutionExplorer.AddFileAsync(
@ -160,7 +160,7 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
}"); }");
} }
[IdeFact] [IdeFact(Skip = "https://github.com/dotnet/razor-tooling/issues/6966")]
public async Task CodeFolding_IfBlock() public async Task CodeFolding_IfBlock()
{ {
await TestServices.SolutionExplorer.AddFileAsync( await TestServices.SolutionExplorer.AddFileAsync(
@ -205,7 +205,7 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
}"); }");
} }
[IdeFact] [IdeFact(Skip = "https://github.com/dotnet/razor-tooling/issues/6966")]
public async Task CodeFolding_ForEach() public async Task CodeFolding_ForEach()
{ {
await TestServices.SolutionExplorer.AddFileAsync( await TestServices.SolutionExplorer.AddFileAsync(
@ -240,7 +240,7 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
}"); }");
} }
[IdeFact] [IdeFact(Skip = "https://github.com/dotnet/razor-tooling/issues/6966")]
public async Task CodeFolding_CodeBlock_Region() public async Task CodeFolding_CodeBlock_Region()
{ {
await TestServices.SolutionExplorer.AddFileAsync( await TestServices.SolutionExplorer.AddFileAsync(

Просмотреть файл

@ -36,9 +36,13 @@ namespace Microsoft.VisualStudio.Extensibility.Testing
public async Task CloseDocumentWindowAsync(CancellationToken cancellationToken) public async Task CloseDocumentWindowAsync(CancellationToken cancellationToken)
{ {
var commandGuid = typeof(VSStd97CmdID).GUID; await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var commandId = VSStd97CmdID.CloseDocument;
await ExecuteCommandAsync(commandGuid, (uint)commandId, cancellationToken); var monitorSelection = await GetRequiredGlobalServiceAsync<SVsShellMonitorSelection, IVsMonitorSelection>(cancellationToken);
ErrorHandler.ThrowOnFailure(monitorSelection.GetCurrentElementValue((uint)VSSELELEMID.SEID_WindowFrame, out var windowFrameObj));
var windowFrame = (IVsWindowFrame)windowFrameObj;
ErrorHandler.ThrowOnFailure(windowFrame.CloseFrame((uint)__FRAMECLOSE.FRAMECLOSE_NoSave));
} }
private async Task ExecuteCommandAsync(Guid commandGuid, uint commandId, CancellationToken cancellationToken) private async Task ExecuteCommandAsync(Guid commandGuid, uint commandId, CancellationToken cancellationToken)

Просмотреть файл

@ -27,7 +27,7 @@ namespace Microsoft.VisualStudio.Razor.IntegrationTests
} }
", ControlledHangMitigatingCancellationToken); ", ControlledHangMitigatingCancellationToken);
await TestServices.Editor.PlaceCaretAsync("//", charsOffset: 2, ControlledHangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("//", charsOffset: 1, ControlledHangMitigatingCancellationToken);
// Act // Act
TestServices.Input.Send("/"); TestServices.Input.Send("/");