diff --git a/azure-pipelines-integration.yml b/azure-pipelines-integration.yml
index 0f3dbd1844fc7f5f5f719bed2e76b03f74d9c731..c7c3350346053e9dabdc9ce41ea85ac4152554e5 100644
--- a/azure-pipelines-integration.yml
+++ b/azure-pipelines-integration.yml
@@ -24,7 +24,9 @@ pr:
jobs:
- job: VS_Integration
- pool: dotnet-external-vs2019-preview
+ pool:
+ name: NetCorePublic-Pool
+ queue: buildpool.windows.10.amd64.vs2019.pre.open
strategy:
maxParallel: 4
matrix:
@@ -68,6 +70,15 @@ jobs:
continueOnError: true
condition: not(succeeded())
+ - task: PublishBuildArtifacts@1
+ displayName: Publish Secondary Logs
+ inputs:
+ PathtoPublish: '$(Build.SourcesDirectory)\artifacts\log2\$(_configuration)'
+ ArtifactName: '$(System.JobAttempt)-Secondary Logs $(_configuration) $(_completionName) $(Build.BuildNumber)'
+ publishLocation: Container
+ continueOnError: true
+ condition: not(succeeded())
+
- task: PublishBuildArtifacts@1
displayName: Publish Screenshots
inputs:
diff --git a/eng/build.ps1 b/eng/build.ps1
index dd47f54d9524935b55921d15b33bcf53d00bc4b2..641f3486f6025de8b617cfbad1a3cbac14c9a919 100644
--- a/eng/build.ps1
+++ b/eng/build.ps1
@@ -345,6 +345,8 @@ function TestUsingOptimizedRunner() {
$env:ROSLYN_TEST_LEGACY_COMPLETION = "true"
}
+ $secondaryLogDir = Join-Path (Join-Path $ArtifactsDir "log2") $configuration
+ Create-Directory $secondaryLogDir
$testResultsDir = Join-Path $ArtifactsDir "TestResults\$configuration"
$binDir = Join-Path $ArtifactsDir "bin"
$runTests = GetProjectOutputBinary "RunTests.exe"
@@ -358,6 +360,7 @@ function TestUsingOptimizedRunner() {
$args = "`"$xunitDir`""
$args += " `"-out:$testResultsDir`""
$args += " `"-logs:$LogDir`""
+ $args += " `"-secondaryLogs:$secondaryLogDir`""
$args += " -nocache"
$args += " -tfm:net472"
diff --git a/src/Compilers/Core/MSBuildTask/Csc.cs b/src/Compilers/Core/MSBuildTask/Csc.cs
index 35f71df1dca506ae3e9e0ad4384a636f942a795d..09601be8757fe8b9c8ff5d19e4f32f3bcd7c1108 100644
--- a/src/Compilers/Core/MSBuildTask/Csc.cs
+++ b/src/Compilers/Core/MSBuildTask/Csc.cs
@@ -149,6 +149,8 @@ public string WarningsNotAsErrors
get { return (string)_store[nameof(WarningsNotAsErrors)]; }
}
+ public string NullableContextOptions { get { return null; } set { } }
+
public string Nullable
{
set { _store[nameof(Nullable)] = value; }
diff --git a/src/Compilers/Extension/CompilerPackage.cs b/src/Compilers/Extension/CompilerPackage.cs
index b57b04eca3cd2c4cfc8a017874841be2900284c5..47e41de72de68cb886237688ccef69d679263a02 100644
--- a/src/Compilers/Extension/CompilerPackage.cs
+++ b/src/Compilers/Extension/CompilerPackage.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using EnvDTE;
@@ -16,6 +17,7 @@ namespace Roslyn.Compilers.Extension
{
[ProvideAutoLoad(UIContextGuids.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
+ [Guid("31C0675E-87A4-4061-A0DD-A4E510FCCF97")]
public sealed class CompilerPackage : AsyncPackage
{
public static string RoslynHive = null;
diff --git a/src/EditorFeatures/Core/Implementation/EncapsulateField/AbstractEncapsulateFieldCommandHandler.cs b/src/EditorFeatures/Core/Implementation/EncapsulateField/AbstractEncapsulateFieldCommandHandler.cs
index 44cca64c29542df0389b63695de093e7f1e63f7f..ae6f86aa732096c84be802bd3d3dc0a31898c7cf 100644
--- a/src/EditorFeatures/Core/Implementation/EncapsulateField/AbstractEncapsulateFieldCommandHandler.cs
+++ b/src/EditorFeatures/Core/Implementation/EncapsulateField/AbstractEncapsulateFieldCommandHandler.cs
@@ -80,6 +80,7 @@ private bool Execute(EncapsulateFieldCommandArgs args, IUIThreadOperationScope w
}
waitScope.AllowCancellation = false;
+ cancellationToken = waitScope.Context.UserCancellationToken;
var finalSolution = result.GetSolutionAsync(cancellationToken).WaitAndGetResult(cancellationToken);
diff --git a/src/Tools/Source/RunTests/Options.cs b/src/Tools/Source/RunTests/Options.cs
index ebbb80eac519ac62a00a020f5572d36a28eb2adb..87e45c91c5a8517adaeea22766d596701631bbc3 100644
--- a/src/Tools/Source/RunTests/Options.cs
+++ b/src/Tools/Source/RunTests/Options.cs
@@ -91,6 +91,11 @@ internal class Options
///
public string LogFilesOutputDirectory { get; set; }
+ ///
+ /// Directory to hold secondary dump files created while running tests.
+ ///
+ public string LogFilesSecondaryOutputDirectory { get; set; }
+
internal static Options Parse(string[] args)
{
if (args == null || args.Any(a => a == null) || args.Length < 2)
@@ -154,6 +159,11 @@ bool isOption(string argument, string optionName, out string value)
opt.LogFilesOutputDirectory = logsPath;
index++;
}
+ else if (isOption(current, "-secondaryLogs", out string secondaryLogsPath))
+ {
+ opt.LogFilesSecondaryOutputDirectory = secondaryLogsPath;
+ index++;
+ }
else if (isOption(current, "-display", out value))
{
if (Enum.TryParse(value, ignoreCase: true, result: out Display display))
@@ -238,6 +248,9 @@ bool isOption(string argument, string optionName, out string value)
opt.LogFilesOutputDirectory = opt.TestResultXmlOutputDirectory;
}
+ // If we weren't passed both -secondaryLogs and -logs but just -logs (or -out), use the same value for -secondaryLogs too.
+ opt.LogFilesSecondaryOutputDirectory ??= opt.LogFilesOutputDirectory;
+
opt.Assemblies = args.Skip(index).ToList();
return allGood ? opt : null;
}
diff --git a/src/Tools/Source/RunTests/ProcDumpUtil.cs b/src/Tools/Source/RunTests/ProcDumpUtil.cs
index 6c8ea4eae10351167d4fc63677beee9efbacc8a2..9142088fd27839d0d4020ba0564c377d10c10ed8 100644
--- a/src/Tools/Source/RunTests/ProcDumpUtil.cs
+++ b/src/Tools/Source/RunTests/ProcDumpUtil.cs
@@ -11,22 +11,27 @@ namespace RunTests
{
private const string KeyProcDumpFilePath = "ProcDumpFilePath";
private const string KeyProcDumpDirectory = "ProcDumpOutputPath";
+ private const string KeyProcDumpSecondaryDirectory = "ProcDumpSecondaryOutputPath";
internal string ProcDumpFilePath { get; }
internal string DumpDirectory { get; }
+ internal string SecondaryDumpDirectory { get; }
- internal ProcDumpInfo(string procDumpFilePath, string dumpDirectory)
+ internal ProcDumpInfo(string procDumpFilePath, string dumpDirectory, string secondaryDumpDirectory)
{
Debug.Assert(Path.IsPathRooted(procDumpFilePath));
Debug.Assert(Path.IsPathRooted(dumpDirectory));
+ Debug.Assert(Path.IsPathRooted(secondaryDumpDirectory));
ProcDumpFilePath = procDumpFilePath;
DumpDirectory = dumpDirectory;
+ SecondaryDumpDirectory = secondaryDumpDirectory;
}
internal void WriteEnvironmentVariables(Dictionary environment)
{
environment[KeyProcDumpFilePath] = ProcDumpFilePath;
environment[KeyProcDumpDirectory] = DumpDirectory;
+ environment[KeyProcDumpSecondaryDirectory] = SecondaryDumpDirectory;
}
internal static ProcDumpInfo? ReadFromEnvironment()
@@ -35,13 +40,14 @@ internal void WriteEnvironmentVariables(Dictionary environment)
var procDumpFilePath = Environment.GetEnvironmentVariable(KeyProcDumpFilePath);
var dumpDirectory = Environment.GetEnvironmentVariable(KeyProcDumpDirectory);
+ var secondaryDumpDirectory = Environment.GetEnvironmentVariable(KeyProcDumpSecondaryDirectory);
- if (!validate(procDumpFilePath) || !validate(dumpDirectory))
+ if (!validate(procDumpFilePath) || !validate(dumpDirectory) || !validate(secondaryDumpDirectory))
{
return null;
}
- return new ProcDumpInfo(procDumpFilePath, dumpDirectory);
+ return new ProcDumpInfo(procDumpFilePath, dumpDirectory, secondaryDumpDirectory);
}
}
diff --git a/src/Tools/Source/RunTests/Program.cs b/src/Tools/Source/RunTests/Program.cs
index 6a5967378bd72f1d7e0299c238d8230bb755a1e8..c73830d3d1e94801769933326128e423090c2d19 100644
--- a/src/Tools/Source/RunTests/Program.cs
+++ b/src/Tools/Source/RunTests/Program.cs
@@ -20,6 +20,11 @@ namespace RunTests
{
internal sealed partial class Program
{
+ private static readonly ImmutableHashSet PrimaryProcessNames = ImmutableHashSet.Create(
+ StringComparer.OrdinalIgnoreCase,
+ "devenv",
+ "xunit.console.x86");
+
internal const int ExitSuccess = 0;
internal const int ExitFailure = 1;
@@ -223,10 +228,12 @@ async Task DumpProcess(Process targetProcess, string procDumpExeFilePath, string
var procDumpInfo = GetProcDumpInfo(options);
if (procDumpInfo != null)
{
- var dumpDir = procDumpInfo.Value.DumpDirectory;
var counter = 0;
foreach (var proc in ProcessUtil.GetProcessTree(Process.GetCurrentProcess()).OrderBy(x => x.ProcessName))
{
+ var dumpDir = PrimaryProcessNames.Contains(proc.ProcessName)
+ ? procDumpInfo.Value.DumpDirectory
+ : procDumpInfo.Value.SecondaryDumpDirectory;
var dumpFilePath = Path.Combine(dumpDir, $"{proc.ProcessName}-{counter}.dmp");
await DumpProcess(proc, procDumpInfo.Value.ProcDumpFilePath, dumpFilePath);
counter++;
@@ -244,7 +251,7 @@ async Task DumpProcess(Process targetProcess, string procDumpExeFilePath, string
{
if (!string.IsNullOrEmpty(options.ProcDumpDirectory))
{
- return new ProcDumpInfo(Path.Combine(options.ProcDumpDirectory, "procdump.exe"), options.LogFilesOutputDirectory);
+ return new ProcDumpInfo(Path.Combine(options.ProcDumpDirectory, "procdump.exe"), options.LogFilesOutputDirectory, options.LogFilesSecondaryOutputDirectory);
}
return null;
diff --git a/src/VisualStudio/Core/Def/Implementation/Preview/PreviewEngine.cs b/src/VisualStudio/Core/Def/Implementation/Preview/PreviewEngine.cs
index f0218ab22a6d864581564aa105aadaa754819376..522ed9236a69e008a4c77a37971d7ff1ddbadf60 100644
--- a/src/VisualStudio/Core/Def/Implementation/Preview/PreviewEngine.cs
+++ b/src/VisualStudio/Core/Def/Implementation/Preview/PreviewEngine.cs
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
@@ -61,9 +62,9 @@ internal class PreviewEngine : ForegroundThreadAffinitizedObject, IVsPreviewChan
{
_topLevelName = topLevelItemName;
_topLevelGlyph = topLevelGlyph;
- _title = title;
- _helpString = helpString;
- _description = description;
+ _title = title ?? throw new ArgumentNullException(nameof(title));
+ _helpString = helpString ?? throw new ArgumentNullException(nameof(helpString));
+ _description = description ?? throw new ArgumentNullException(nameof(description));
_newSolution = newSolution.WithMergedLinkedFileChangesAsync(oldSolution, cancellationToken: CancellationToken.None).Result;
_oldSolution = oldSolution;
_diffSelector = componentModel.GetService();
diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs
index fecd883c20c31b666b5b8a632884e8180094ad63..3f1e3034cf71bdc645e7a5bd5d410f7f663b0ab3 100644
--- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs
+++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs
@@ -33,7 +33,7 @@ static void Main(string[] args)
}
}";
- [WpfFact]
+ [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35701")]
[Trait(Traits.Feature, Traits.Features.EncapsulateField)]
public void EncapsulateThroughCommand()
{
diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicEncapsulateField.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicEncapsulateField.cs
index 03ab8930668f9964854651b097f67fb60c7d11ac..efa308d3c0bef0466afa1a1f518131294bbd25bc 100644
--- a/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicEncapsulateField.cs
+++ b/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicEncapsulateField.cs
@@ -28,7 +28,7 @@ Sub Main()
End Sub
End Module";
- [WpfFact]
+ [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35701")]
[Trait(Traits.Feature, Traits.Features.EncapsulateField)]
public void EncapsulateThroughCommand()
{
diff --git a/src/VisualStudio/IntegrationTest/TestSetup/IntegrationTestServicePackage.cs b/src/VisualStudio/IntegrationTest/TestSetup/IntegrationTestServicePackage.cs
index e986b1308222fb5ae195e21adc2a1e632f2cd2b4..8dbe6cf0af2e102393a40aa8661e8abeb9d1cf15 100644
--- a/src/VisualStudio/IntegrationTest/TestSetup/IntegrationTestServicePackage.cs
+++ b/src/VisualStudio/IntegrationTest/TestSetup/IntegrationTestServicePackage.cs
@@ -16,12 +16,21 @@ namespace Microsoft.VisualStudio.IntegrationTest.Setup
[ProvideAutoLoad(UIContextGuids80.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)]
public sealed class IntegrationTestServicePackage : AsyncPackage
{
+ private static readonly Guid s_compilerPackage = new Guid("31C0675E-87A4-4061-A0DD-A4E510FCCF97");
+
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress progress)
{
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
+ var shell = (IVsShell)await GetServiceAsync(typeof(SVsShell));
+ ErrorHandler.ThrowOnFailure(shell.IsPackageInstalled(s_compilerPackage, out var installed));
+ if (installed != 0)
+ {
+ await ((IVsShell7)shell).LoadPackageAsync(s_compilerPackage);
+ }
+
IntegrationTestServiceCommands.Initialize(this);
}
}
diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/Dialog_OutOfProc.cs b/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/Dialog_OutOfProc.cs
index 46ad922fdcc9cf29c0dc1854db2e301de65c39c0..f9878ca685d8e8043793b9ceb6b0d371d5f84f28 100644
--- a/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/Dialog_OutOfProc.cs
+++ b/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/Dialog_OutOfProc.cs
@@ -14,17 +14,21 @@ public Dialog_OutOfProc(VisualStudioInstance visualStudioInstance)
public void VerifyOpen(string dialogName)
{
+ using var cancellationTokenSource = new CancellationTokenSource(Helper.HangMitigatingTimeout);
+
// FindDialog will wait until the dialog is open, so the return value is unused.
- DialogHelpers.FindDialogByName(GetMainWindowHWnd(), dialogName, isOpen: true, CancellationToken.None);
+ DialogHelpers.FindDialogByName(GetMainWindowHWnd(), dialogName, isOpen: true, cancellationTokenSource.Token);
// Wait for application idle to ensure the dialog is fully initialized
- VisualStudioInstance.WaitForApplicationIdle(CancellationToken.None);
+ VisualStudioInstance.WaitForApplicationIdle(cancellationTokenSource.Token);
}
public void VerifyClosed(string dialogName)
{
+ using var cancellationTokenSource = new CancellationTokenSource(Helper.HangMitigatingTimeout);
+
// FindDialog will wait until the dialog is closed, so the return value is unused.
- DialogHelpers.FindDialogByName(GetMainWindowHWnd(), dialogName, isOpen: false, CancellationToken.None);
+ DialogHelpers.FindDialogByName(GetMainWindowHWnd(), dialogName, isOpen: false, cancellationTokenSource.Token);
}
public void Click(string dialogName, string buttonName)
diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs b/src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs
index 9f697a81ba004a40bf7b3ddca91b60c8a7c502c5..ab7b551c1ad789a792020ce40bd5504e5d08f599 100644
--- a/src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs
+++ b/src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs
@@ -11,6 +11,7 @@
using System.Threading.Tasks;
using EnvDTE;
using Microsoft.VisualStudio.Setup.Configuration;
+using Microsoft.Win32;
using RunTests;
using Process = System.Diagnostics.Process;
@@ -332,6 +333,18 @@ private static Process StartNewVisualStudioProcess(string installationPath, int
var useAsyncCompletionSetting = usingAsyncCompletion ? 1 : -1;
Process.Start(vsRegEditExeFile, $"set \"{installationPath}\" {Settings.Default.VsRootSuffix} HKCU \"ApplicationPrivateSettings\\WindowManagement\\Options\" UseAsyncCompletion string \"1*System.Int32*{useAsyncCompletionSetting}\"").WaitForExit();
+ var disabledFlights = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\ABExp\LocalTest", "DisabledFlights", Array.Empty()) as string[] ?? Array.Empty();
+ if (usingAsyncCompletion)
+ {
+ disabledFlights = disabledFlights.Where(flight => !string.Equals(flight, "completionapi", StringComparison.OrdinalIgnoreCase)).ToArray();
+ }
+ else if (!disabledFlights.Contains("completionapi", StringComparer.OrdinalIgnoreCase))
+ {
+ disabledFlights = disabledFlights.Concat(new[] { "completionapi" }).ToArray();
+ }
+
+ Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\ABExp\LocalTest", "DisabledFlights", disabledFlights, RegistryValueKind.MultiString);
+
// Disable text editor error reporting because it pops up a dialog. We want to either fail fast in our
// custom handler or fail silently and continue testing.
Process.Start(vsRegEditExeFile, $"set \"{installationPath}\" {Settings.Default.VsRootSuffix} HKCU \"Text Editor\" \"Report Exceptions\" dword 0").WaitForExit();