Skip to content

Commit

Permalink
Merge pull request dotnet#70983 from sharwell/use-cps-2
Browse files Browse the repository at this point in the history
Use CPS for tests where saving documents needs to be reliable
  • Loading branch information
sharwell authored Dec 28, 2023
2 parents 072cbff + 9102482 commit a5daa7d
Show file tree
Hide file tree
Showing 18 changed files with 1,058 additions and 66 deletions.
3 changes: 2 additions & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<RoslynDiagnosticsNugetPackageVersion>3.11.0-beta1.23364.2</RoslynDiagnosticsNugetPackageVersion>
<MicrosoftCodeAnalysisNetAnalyzersVersion>8.0.0-preview.23468.1</MicrosoftCodeAnalysisNetAnalyzersVersion>
<MicrosoftCodeAnalysisTestingVersion>1.1.2-beta1.23411.1</MicrosoftCodeAnalysisTestingVersion>
<MicrosoftVisualStudioExtensibilityTestingVersion>0.1.149-beta</MicrosoftVisualStudioExtensibilityTestingVersion>
<MicrosoftVisualStudioExtensibilityTestingVersion>0.1.187-beta</MicrosoftVisualStudioExtensibilityTestingVersion>
<!-- CodeStyleAnalyzerVersion should we updated together with version of dotnet-format in dotnet-tools.json -->
<CodeStyleAnalyzerVersion>4.8.0-3.final</CodeStyleAnalyzerVersion>
<VisualStudioEditorPackagesVersion>17.8.222</VisualStudioEditorPackagesVersion>
Expand Down Expand Up @@ -232,6 +232,7 @@
<SystemDrawingCommonVersion>7.0.0</SystemDrawingCommonVersion>
<SystemIOFileSystemVersion>4.3.0</SystemIOFileSystemVersion>
<SystemIOFileSystemPrimitivesVersion>4.3.0</SystemIOFileSystemPrimitivesVersion>
<SystemIOHashingVersion>8.0.0</SystemIOHashingVersion>
<SystemIOPipesAccessControlVersion>5.0.0</SystemIOPipesAccessControlVersion>
<SystemIOPipelinesVersion>7.0.0</SystemIOPipelinesVersion>
<SystemManagementVersion>7.0.0</SystemManagementVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
// See the LICENSE file in the project root for more information.

using System;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Extensibility.Testing;
using Microsoft.VisualStudio.LanguageServices;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Test.Utilities;
using Xunit;
Expand All @@ -22,6 +25,7 @@ namespace Roslyn.VisualStudio.IntegrationTests
[IdeSettings(MinVersion = VisualStudioVersion.VS2022, RootSuffix = "RoslynDev", MaxAttempts = 2)]
public abstract class AbstractIntegrationTest : AbstractIdeIntegrationTest
{
private static string? s_catalogCacheFolder;
private static AsynchronousOperationListenerProvider? s_listenerProvider;
private static VisualStudioWorkspace? s_workspace;

Expand All @@ -35,6 +39,35 @@ static AbstractIntegrationTest()
RuntimeHelpers.RunModuleConstructor(typeof(TestBase).Module.ModuleHandle);
TestTraceListener.Install();

DataCollectionService.RegisterCustomLogger(
static fileName =>
{
if (s_catalogCacheFolder is null)
return;

var file = Path.Combine(s_catalogCacheFolder, "Microsoft.VisualStudio.Default.err");
if (File.Exists(file))
{
string content;
try
{
content = File.ReadAllText(file);
}
catch (Exception ex)
{
content =
$"""
Exception thrown while reading '{file}':
{ex}
""";
}

File.WriteAllText(fileName, content);
}
},
logId: "MEF",
extension: "err");

IdeStateCollector.RegisterCustomState(
"Pending asynchronous operations",
static () =>
Expand Down Expand Up @@ -106,6 +139,12 @@ public override async Task InitializeAsync()
{
await base.InitializeAsync();

if (s_catalogCacheFolder is null)
{
var componentModel = await TestServices.Shell.GetRequiredGlobalServiceAsync<SVsComponentModelHost, IVsComponentModelHost>(HangMitigatingCancellationToken);
ErrorHandler.ThrowOnFailure(componentModel.GetCatalogCacheFolder(out s_catalogCacheFolder));
}

s_listenerProvider ??= await TestServices.Shell.GetComponentModelServiceAsync<AsynchronousOperationListenerProvider>(HangMitigatingCancellationToken);
s_workspace ??= await TestServices.Shell.GetComponentModelServiceAsync<VisualStudioWorkspace>(HangMitigatingCancellationToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static void Main(string[] args)
", HangMitigatingCancellationToken);

await TestServices.Workspace.WaitForAsyncOperationsAsync(FeatureAttribute.Workspace, HangMitigatingCancellationToken);
await TestServices.Debugger.SetBreakpointAsync("Program.cs", "}", HangMitigatingCancellationToken);
await TestServices.Debugger.SetBreakpointAsync(ProjectName, "Program.cs", "}", HangMitigatingCancellationToken);
await TestServices.Debugger.GoAsync(waitForBreakMode: true, HangMitigatingCancellationToken);
await TestServices.ImmediateWindow.ShowAsync(HangMitigatingCancellationToken);
await TestServices.ImmediateWindow.ClearAllAsync(HangMitigatingCancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ internal partial class DebuggerInProcess
return (EnvDTE100.Debugger5)dte.Debugger;
}

public Task SetBreakpointAsync(string fileName, string text, CancellationToken cancellationToken)
=> SetBreakpointAsync(fileName, text, charsOffset: 0, cancellationToken);
public Task SetBreakpointAsync(string projectName, string fileName, string text, CancellationToken cancellationToken)
=> SetBreakpointAsync(projectName, fileName, text, charsOffset: 0, cancellationToken);

public async Task SetBreakpointAsync(string fileName, string text, int charsOffset, CancellationToken cancellationToken)
public async Task SetBreakpointAsync(string projectName, string fileName, string text, int charsOffset, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

Expand All @@ -47,16 +47,18 @@ public async Task SetBreakpointAsync(string fileName, string text, int charsOffs

var caretPosition = await TestServices.Editor.GetCaretPositionAsync(cancellationToken);
caretPosition.BufferPosition.GetLineAndCharacter(out var lineNumber, out var characterIndex);
await SetBreakpointAsync(fileName, lineNumber, characterIndex + charsOffset, cancellationToken);
await SetBreakpointAsync(projectName, fileName, lineNumber, characterIndex + charsOffset, cancellationToken);
}

public async Task SetBreakpointAsync(string fileName, int lineNumber, int characterIndex, CancellationToken cancellationToken)
public async Task SetBreakpointAsync(string projectName, string fileName, int lineNumber, int characterIndex, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

var breakpointFile = await TestServices.SolutionExplorer.GetAbsolutePathForProjectRelativeFilePathAsync(projectName, fileName, cancellationToken);

var debugger = await GetDebuggerAsync(cancellationToken);
// Need to increment the line number because editor line numbers starts from 0 but the debugger ones starts from 1.
debugger.Breakpoints.Add(File: fileName, Line: lineNumber + 1, Column: characterIndex);
debugger.Breakpoints.Add(File: breakpointFile, Line: lineNumber + 1, Column: characterIndex);
}

public async Task GoAsync(bool waitForBreakMode, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Roslyn.VisualStudio.NewIntegrationTests.InProcess;

internal enum EditAndContinueResult
{
NoChanges = 0,

RudeEdits = 1,

BuildError = 2,

Succeeded = 3,

ApplyUpdatesFailure = 4,

// This gets returned when the result has already been handled by the provider,
// and no further action is required.
NoReport = 5,

NotSupported = 6,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Roslyn.VisualStudio.NewIntegrationTests.InProcess;

internal enum HotReloadAction
{
None,
Cancel,
Edit,
Disable,
Revert,
Ignore,
Restart,
Stop,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

namespace Roslyn.VisualStudio.NewIntegrationTests.InProcess;

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("4F6E5436-F098-45FF-B85F-7AE940DFCA44")]
internal interface IHotReloadUIService
{
int ShowHotReloadDialog(bool isManaged, EditAndContinueResult result, [In][MarshalAs(UnmanagedType.BStr)] string errorMessage);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

namespace Roslyn.VisualStudio.NewIntegrationTests.InProcess;

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("1DD71F22-C880-46be-A462-A0A5542BC939")]
internal interface IVsMessageBoxService
{
[PreserveSig]
int ShowMessageBox(
IntPtr hWndOwner,
IntPtr hInstance,
[MarshalAs(UnmanagedType.LPWStr)] string lpszText,
[MarshalAs(UnmanagedType.LPWStr)] string lpszCaption,
uint dwStyle,
IntPtr lpszIcon,
IntPtr dwContextHelpId,
IntPtr pfnMessageBoxCallback,
uint dwLangID,
out int pidButton);
}
Loading

0 comments on commit a5daa7d

Please sign in to comment.