未验证 提交 3191dcda 编写于 作者: S Sam Harwell 提交者: GitHub

Merge pull request #27838 from sharwell/test-stability-fixes

Test stability fixes
......@@ -41,6 +41,7 @@ protected AbstractIntegrationTest(VisualStudioInstanceFactory instanceFactory)
catch
{
_messageFilter.Dispose();
_messageFilter = null;
throw;
}
}
......@@ -60,8 +61,14 @@ public virtual async Task InitializeAsync()
}
}
public Task DisposeAsync()
/// <summary>
/// This method implements <see cref="IAsyncLifetime.DisposeAsync"/>, and is used for releasing resources
/// created by <see cref="IAsyncLifetime.InitializeAsync"/>. This method is only called if
/// <see cref="InitializeAsync"/> completes successfully.
/// </summary>
public virtual Task DisposeAsync()
{
_visualStudioContext.Dispose();
return Task.CompletedTask;
}
......@@ -80,18 +87,17 @@ protected void Wait(double seconds)
Thread.Sleep(timeout);
}
/// <summary>
/// This method provides the implementation for <see cref="IDisposable.Dispose"/>. This method via the
/// <see cref="IDisposable"/> interface (i.e. <paramref name="disposing"/> is <see langword="true"/>) if the
/// constructor completes successfully. The <see cref="InitializeAsync"/> may or may not have completed
/// successfully.
/// </summary>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
try
{
_visualStudioContext.Dispose();
}
finally
{
_messageFilter.Dispose();
}
_messageFilter.Dispose();
}
}
......
......@@ -215,12 +215,7 @@ class C
VisualStudio.Editor.Verify.CodeAction(
"Use expression body for properties",
applyFix: true,
fixAllScope: FixAllScope.Project,
blockUntilComplete: false);
var expectedTitle = "Preview Changes - Fix all occurrences";
VisualStudio.PreviewChangesDialog.VerifyOpen(expectedTitle, Helper.HangMitigatingTimeout);
VisualStudio.PreviewChangesDialog.ClickApplyAndWaitForFeature(expectedTitle, FeatureAttribute.DiagnosticService);
fixAllScope: FixAllScope.Project);
Assert.Equal(expectedText, VisualStudio.Editor.GetText());
......@@ -243,11 +238,7 @@ class C
VisualStudio.Editor.Verify.CodeAction(
"Use block body for properties",
applyFix: true,
fixAllScope: FixAllScope.Project,
blockUntilComplete: false);
VisualStudio.PreviewChangesDialog.VerifyOpen(expectedTitle, Helper.HangMitigatingTimeout);
VisualStudio.PreviewChangesDialog.ClickApplyAndWaitForFeature(expectedTitle, FeatureAttribute.DiagnosticService);
fixAllScope: FixAllScope.Project);
expectedText = @"
class C
......
......@@ -22,14 +22,10 @@ public override async Task InitializeAsync()
VisualStudio.InteractiveWindow.SubmitText("#cls");
}
protected override void Dispose(bool disposing)
public override Task DisposeAsync()
{
if (disposing)
{
VisualStudio.ExecuteCommand(WellKnownCommandNames.Edit_SelectionCancel);
}
base.Dispose(disposing);
VisualStudio.ExecuteCommand(WellKnownCommandNames.Edit_SelectionCancel);
return base.DisposeAsync();
}
[WpfFact]
......
......@@ -22,16 +22,12 @@ public override async Task InitializeAsync()
VisualStudio.Workspace.SetUseSuggestionMode(true);
}
protected override void Dispose(bool disposing)
public override Task DisposeAsync()
{
if (disposing)
{
VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.InteractiveWindow.ClearReplText();
VisualStudio.InteractiveWindow.Reset();
}
base.Dispose(disposing);
VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.InteractiveWindow.ClearReplText();
VisualStudio.InteractiveWindow.Reset();
return base.DisposeAsync();
}
[WpfFact]
......
......@@ -32,11 +32,14 @@ public static IUIAutomationElement GetOpenDialogById(IntPtr visualStudioHWnd, st
public static IUIAutomationElement FindDialogByAutomationId(IntPtr visualStudioHWnd, string dialogAutomationId, bool isOpen, bool wait = true)
{
return Retry(
_ => FindDialogWorker(visualStudioHWnd, dialogAutomationId),
stoppingCondition: (automationElement, _) => !wait || (isOpen ? automationElement != null : automationElement == null),
delay: TimeSpan.FromMilliseconds(250),
CancellationToken.None);
using (var cancellationTokenSource = new CancellationTokenSource(Helper.HangMitigatingTimeout))
{
return Retry(
_ => FindDialogWorker(visualStudioHWnd, dialogAutomationId),
stoppingCondition: (automationElement, _) => !wait || (isOpen ? automationElement != null : automationElement == null),
delay: TimeSpan.FromMilliseconds(250),
cancellationTokenSource.Token);
}
}
/// <summary>
......@@ -124,7 +127,11 @@ public static void PressButtonWithName(IntPtr visualStudioHWnd, string dialogAut
/// </summary>
public static void PressButtonWithNameFromDialogWithName(IntPtr visualStudioHWnd, string dialogName, string buttonName)
{
var dialogAutomationElement = FindDialogByName(visualStudioHWnd, dialogName, isOpen: true, CancellationToken.None);
IUIAutomationElement dialogAutomationElement;
using (var cancellationTokenSource = new CancellationTokenSource(Helper.HangMitigatingTimeout))
{
dialogAutomationElement = FindDialogByName(visualStudioHWnd, dialogName, isOpen: true, cancellationTokenSource.Token);
}
var buttonAutomationElement = dialogAutomationElement.FindDescendantByName(buttonName);
buttonAutomationElement.Invoke();
......
......@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
......@@ -15,6 +16,7 @@
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Text.Tagging;
using Roslyn.Utilities;
using OLECMDEXECOPT = Microsoft.VisualStudio.OLE.Interop.OLECMDEXECOPT;
using ThreadHelper = Microsoft.VisualStudio.Shell.ThreadHelper;
......@@ -319,7 +321,7 @@ private async Task<IEnumerable<ISuggestedAction>> GetLightBulbActionsAsync(ILigh
public void ApplyLightBulbAction(string actionName, FixAllScope? fixAllScope, bool blockUntilComplete)
{
var lightBulbAction = GetLightBulbApplicationAction(actionName, fixAllScope);
var lightBulbAction = GetLightBulbApplicationAction(actionName, fixAllScope, blockUntilComplete);
var task = ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
......@@ -340,7 +342,7 @@ public void ApplyLightBulbAction(string actionName, FixAllScope? fixAllScope, bo
private void BeginInvokeExecuteOnActiveView(Action<IWpfTextView> action)
=> BeginInvokeOnUIThread(GetExecuteOnActionViewCallback(action));
private Func<IWpfTextView, Task> GetLightBulbApplicationAction(string actionName, FixAllScope? fixAllScope)
private Func<IWpfTextView, Task> GetLightBulbApplicationAction(string actionName, FixAllScope? fixAllScope, bool willBlockUntilComplete)
{
return async view =>
{
......@@ -378,6 +380,17 @@ private void BeginInvokeExecuteOnActiveView(Action<IWpfTextView> action)
throw new InvalidOperationException($"Unable to find FixAll in {fixAllScope.ToString()} code fix for suggested action '{action.DisplayText}'.");
}
if (willBlockUntilComplete
&& action is FixAllSuggestedAction fixAllSuggestedAction
&& fixAllSuggestedAction.CodeAction is FixSomeCodeAction fixSomeCodeAction)
{
// Ensure the preview changes dialog will not be shown. Since the operation 'willBlockUntilComplete',
// the caller would not be able to interact with the preview changes dialog, and the tests would
// either timeout or deadlock.
var field = typeof(FixSomeCodeAction).GetField("_showPreviewChangesDialog", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(fixSomeCodeAction, false);
}
if (string.IsNullOrEmpty(actionName))
{
return;
......
......@@ -105,10 +105,19 @@ public async Task<VisualStudioInstanceContext> GetNewOrUsedInstanceAsync(Immutab
{
ThrowExceptionIfAlreadyHasActiveContext();
bool shouldStartNewInstance = ShouldStartNewInstance(requiredPackageIds);
await UpdateCurrentlyRunningInstanceAsync(requiredPackageIds, shouldStartNewInstance).ConfigureAwait(false);
try
{
bool shouldStartNewInstance = ShouldStartNewInstance(requiredPackageIds);
await UpdateCurrentlyRunningInstanceAsync(requiredPackageIds, shouldStartNewInstance).ConfigureAwait(false);
return new VisualStudioInstanceContext(_currentlyRunningInstance, this);
return new VisualStudioInstanceContext(_currentlyRunningInstance, this);
}
catch
{
// Make sure the next test doesn't try to reuse the same instance
NotifyCurrentInstanceContextDisposed(canReuse: false);
throw;
}
}
internal void NotifyCurrentInstanceContextDisposed(bool canReuse)
......@@ -176,14 +185,17 @@ private async Task UpdateCurrentlyRunningInstanceAsync(ImmutableHashSet<string>
}
else
{
// We are going to reuse the currently running instance, so ensure that we grab the host Process and Dte
// We are going to reuse the currently running instance, so ensure that we grab the host Process and DTE
// before cleaning up any hooks or remoting services created by the previous instance. We will then
// create a new VisualStudioInstance from the previous to ensure that everything is in a 'clean' state.
//
// We create a new DTE instance in the current context since the COM object could have been separated
// from its RCW during the previous test.
Debug.Assert(_currentlyRunningInstance != null);
hostProcess = _currentlyRunningInstance.HostProcess;
dte = _currentlyRunningInstance.Dte;
dte = await IntegrationHelper.WaitForNotNullAsync(() => IntegrationHelper.TryLocateDteForProcess(hostProcess)).ConfigureAwait(false);
supportedPackageIds = _currentlyRunningInstance.SupportedPackageIds;
installationPath = _currentlyRunningInstance.InstallationPath;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册