From 5e59fa403297516710222264b5df53496e379f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Tue, 6 Oct 2020 11:17:58 +0200 Subject: [PATCH] Update from 16.8 (#2588) * Hide -release in console * Add param block * Match on whole branch name * Set var * Change assertion * Trim version * Update dependencies from https://github.com/dotnet/arcade build 20200602.3 (#2456) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.SwaggerGenerator.MSBuild From Version 5.0.0-beta.20052.1 -> To Version 1.0.0-beta.20302.3 Co-authored-by: dotnet-maestro[bot] * Update feeds * Revert to previous dotnet version * Added new exception handling (#2461) * Test space added * Exception handler was added to catch AccessDeniedException while trying to create TestResults folder * Remove unnecessary space * Deleted unnecessary test. Changed console message and corrected folder path in that message * Remove unnecessary dot * Removed unnecessary lines and usings and coreccted exception message * Removed unnecessary line * Updating resource files * New exception handling was added * Formatted exception message * Adding test run attachments processing (#2463) * v1 * Merging v1 * Rename to MultiTestRunsFinalization * New version * More changes * More changes * Next changes * Fix * test * More changes * Dmc chagnes * next * small changes * compiled * More changes * acceptance tests green * Review comments #1 * Resolving more comments * Tests for design mode client * Tests for events handler * revert not related changes * More changes * Compiling OK, tests OK * Unit tests for manager * More changes * More tests * tests for reqeust sender * more tests * Tests for cancelling * Acceptance tests done * Remove not used stuff * Fix comments * Fix race condition in test * Fix another race condition * Fix converting to xml * fix next test * fix test * Next changes * Review changes #1 * Fixing multi test finalization manager tests * Fixes * Fix last unit test * Fix acceptance tests * Progress feature, compiling + unit tests * acceptance tests changes * More changes * Fixing resources accesability * Fix test * Fix race conditions in acceptance tests * RFC changes merged * Log warning in case of unexpected message id * Fix spelling * Additional comment * Restore some stuff in interfaces * Big renaming * Added processingSettings * Fix naming * Move explanation to * Add environment variables to enable MacOS dump * Fixed code coverage compatibility issue (#2527) Fixed code coverage compatibility issue * Print version of the product in log (#2535) * Trigger dumps asynchronously (#2533) * Run each dump in a task in netclient dumper * More reasonable timeout * Revert "Trigger dumps asynchronously (#2533)" (#2541) This reverts commit 3454261faa4cf39d03758f339ad010dc0a8a3c8f. * Remove env variables * Remove sleeps and extra process dumps from blame * Fix blame parameter, warning, and add all testhosts to be ngend (#2579) * Forward merge fixes from master to rc2 (#2581) * Avoid logging >Task returned false but did not log an error.< (#2557) * Avoid logging >Task returned false but did not log an error.< on test failure * Add VSTEST_BUILD_DEBUG env var * Using namespaces * Invert the switch because it will be still backwards in the final release * Use bitness from process or OS (#2571) * Do not force .NET4.5 in case legacy test settings are provided (#2545) * Do not force .NET4.5 in case legacy test settings are provided * Net core app * Fix runconfig * Default platform * Generate release notes in pipeline * Fix release-notes-script Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] Co-authored-by: Sanan Yuzbashiyev Co-authored-by: Jakub Chocholowicz <59966772+jakubch1@users.noreply.github.com> Co-authored-by: Codrin-Victor Poienaru --- scripts/write-release-notes.ps1 | 119 ++++++++ .../BlameCollector.cs | 17 +- .../Interfaces/IProcessDumpUtility.cs | 3 +- .../ProcessDumpUtility.cs | 4 +- .../WindowsHangDumper.cs | 2 +- src/package/VSIXProject/TestPlatform.csproj | 16 ++ .../BlameCollectorTests.cs | 49 +++- .../EnableBlameArgumentProcessorTests.cs | 262 +++++++++++++++++- 8 files changed, 445 insertions(+), 27 deletions(-) create mode 100644 scripts/write-release-notes.ps1 diff --git a/scripts/write-release-notes.ps1 b/scripts/write-release-notes.ps1 new file mode 100644 index 0000000000..b356f88af9 --- /dev/null +++ b/scripts/write-release-notes.ps1 @@ -0,0 +1,119 @@ +[CmdletBinding()] +param +( + [string] $Path = ".", + # if this is a pre-release or stable version + [switch] $Stable, + # externally provide the version number we will use + [string] $PackageVersion, + # in CI we don't know the end tag, so we diff till the current commit + [switch] $EndWithLatestCommit +) + +if ($EndWithLatestCommit -and [string]::IsNullOrWhiteSpace($PackageVersion)) { + throw "EndWithLatestCommit was enabled, provide PackageVersion in this format 16.8.0-preview-20200924-01, or this format 16.8.0." +} + +$repoUrl = $(if ((git -C $Path remote -v) -match "upstream") { + git -C $Path remote get-url --push upstream + } + else { + git -C $Path remote get-url --push origin + })-replace "\.git$" + +# list all tags on this branch ordered by creator date to get the latest, stable or pre-release tag. +# For stable release we choose only tags without any dash, for pre-release we choose all tags. +$tags = git -C $Path tag -l --sort=creatordate | Where-Object { $_ -match "v\d+\.\d+\.\d+.*" -and (-not $Stable -or $_ -notlike '*-*') } + +if ($EndWithLatestCommit) { + # in CI we don't have the tag yet, so we show changes between the most recent tag, and this commit + # we figure out the tag from the package version that is set by vsts-prebuild + $start = $tags | Select-Object -Last 1 + $end = git -C $Path rev-parse HEAD + $tag = "v$PackageVersion" +} +else { + # normally we show changes between the latest two tags + $start, $end = $tags | Select-Object -Last 2 + $tag = $end +} + +# # override the tags to use if you need +# $start = "v16.8.0-preview-20200812-03" +# $end = $tag = "v16.8.0-preview-20200921-01" + + +Write-Host "Generating release notes for $start..$end$(if ($EndWithLatestCommit) { " (expected tag: $tag)" })" + +$sourceBranch = $branch = git -C $Path rev-parse --abbrev-ref HEAD +if ($sourceBranch -eq "HEAD") { + # when CI checks out just the single commit, https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml + $sourceBranch = $env:BUILD_SOURCEBRANCH -replace "^refs/heads/" +} + +if ([string]::IsNullOrWhiteSpace($branch)) { + throw "Branch is null or empty!" +} + +if ([string]::IsNullOrWhiteSpace($sourceBranch)) { + throw "SourceBranch is null or empty!" +} + +Write-Host "Branch is $branch" +Write-Host "SourceBranch is $sourceBranch" +$branchesWithStartTag = git -C $Path branch --contains tags/$start + +if (-not $branchesWithStartTag -or -not ($branchesWithStartTag -match $branch)) { + Write-Host "This branch $branch$(if($branch -ne $sourceBranch){" ($sourceBranch)"}), does not contain the starting tag $start. Skipping generating release notes." + if ($branchesWithStartTag) { + Write-Host "The tag is present on branches:`n$($branchesWithStartTag)." + } + return +} +else { + Write-Host "Branch $branch$(if($branch -ne $sourceBranch){" ($sourceBranch)"}) has tag $start, getting log since that." +} + +$prUrl = "$repoUrl/pull/" +$v = $tag -replace '^v' +$b = if ($Stable) { $v } else { $tag -replace '.*?(\d+-\d+)$', '$1' } +# using .. because I want to know the changes that are on this branch, but don't care about the changes that I don't have https://stackoverflow.com/a/24186641/3065397 +$log = (git -C $Path log "$start..$end" --oneline --pretty="format:%s" --first-parent) +$issues = $log | ForEach-Object { + if ($_ -match '^(?.+)\s\(#(?\d+)\)?$') { + $message = "* $($matches.message)" + if ($matches.pr) { + $pr = $matches.pr + $message += " [#$pr]($prUrl$pr)" + } + + $message + } + else + { + "* $_" + } +} + +$output = @" + +See the release notes [here](https://github.com/microsoft/vstest-docs/blob/master/docs/releases.md#$($v -replace '\.')). + +------------------------------- + +## $v + +### Issue Fixed +$($issues -join "`n") + +See full log [here]($repoUrl/compare/$start...$tag) + +### Drops + +* TestPlatform vsix: [$v](https://vsdrop.corp.microsoft.com/file/v1/Products/DevDiv/microsoft/vstest/$sourceBranch/$b;/TestPlatform.vsix) +* Microsoft.TestPlatform.ObjectModel : [$v](https://www.nuget.org/packages/Microsoft.TestPlatform.ObjectModel/$v) +"@ + + +$output +$output | clip diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs index 3f8ad9bcd3..57b4cd624f 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs @@ -348,6 +348,7 @@ private void ValidateAndAddHangBasedProcessDumpParameters(XmlElement collectDump break; + // allow HangDumpType attribute to be used on the hang dump this is the prefered way case XmlAttribute attribute when string.Equals(attribute.Name, Constants.HangDumpTypeKey, StringComparison.OrdinalIgnoreCase): if (string.Equals(attribute.Value, Constants.FullConfigurationValue, StringComparison.OrdinalIgnoreCase) || string.Equals(attribute.Value, Constants.MiniConfigurationValue, StringComparison.OrdinalIgnoreCase)) @@ -361,6 +362,20 @@ private void ValidateAndAddHangBasedProcessDumpParameters(XmlElement collectDump break; + // allow DumpType attribute to be used on the hang dump for backwards compatibility + case XmlAttribute attribute when string.Equals(attribute.Name, Constants.DumpTypeKey, StringComparison.OrdinalIgnoreCase): + + if (string.Equals(attribute.Value, Constants.FullConfigurationValue, StringComparison.OrdinalIgnoreCase) || string.Equals(attribute.Value, Constants.MiniConfigurationValue, StringComparison.OrdinalIgnoreCase)) + { + this.processFullDumpEnabled = string.Equals(attribute.Value, Constants.FullConfigurationValue, StringComparison.OrdinalIgnoreCase); + } + else + { + this.logger.LogWarning(this.context.SessionDataCollectionContext, string.Format(CultureInfo.CurrentUICulture, Resources.Resources.BlameParameterValueIncorrect, attribute.Name, Constants.FullConfigurationValue, Constants.MiniConfigurationValue)); + } + + break; + default: this.logger.LogWarning(this.context.SessionDataCollectionContext, string.Format(CultureInfo.CurrentUICulture, Resources.Resources.BlameParameterKeyIncorrect, blameAttribute.Name)); @@ -454,7 +469,7 @@ private void SessionEndedHandler(object sender, SessionEndEventArgs args) { try { - var dumpFiles = this.processDumpUtility.GetDumpFiles(); + var dumpFiles = this.processDumpUtility.GetDumpFiles(warnOnNoDumpFiles: this.collectDumpAlways); foreach (var dumpFile in dumpFiles) { if (!string.IsNullOrEmpty(dumpFile)) diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IProcessDumpUtility.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IProcessDumpUtility.cs index 74acf34e53..aca460dc0d 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IProcessDumpUtility.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IProcessDumpUtility.cs @@ -11,10 +11,11 @@ public interface IProcessDumpUtility /// /// Get generated dump files /// + /// Writes warning when no dump file is found. /// /// Path of dump file /// - IEnumerable GetDumpFiles(); + IEnumerable GetDumpFiles(bool warnOnNoDumpFiles = true); /// /// Launch proc dump process diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/ProcessDumpUtility.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/ProcessDumpUtility.cs index 6065f1c4e3..8c7166e815 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/ProcessDumpUtility.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/ProcessDumpUtility.cs @@ -51,7 +51,7 @@ public ProcessDumpUtility(IProcessHelper processHelper, IFileHelper fileHelper, }; /// - public IEnumerable GetDumpFiles() + public IEnumerable GetDumpFiles(bool warnOnNoDumpFiles = true) { if (!this.wasHangDumped) { @@ -82,7 +82,7 @@ public IEnumerable GetDumpFiles() } } - if (!foundDumps.Any()) + if (warnOnNoDumpFiles && !foundDumps.Any()) { EqtTrace.Error($"ProcessDumpUtility.GetDumpFile: Could not find any dump file in {this.hangDumpDirectory}."); throw new FileNotFoundException(Resources.Resources.DumpFileNotGeneratedErrorMessage); diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/WindowsHangDumper.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/WindowsHangDumper.cs index c0aeed16c2..18e081b31a 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/WindowsHangDumper.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/WindowsHangDumper.cs @@ -27,7 +27,7 @@ public WindowsHangDumper(Action logWarning) public void Dump(int processId, string outputDirectory, DumpTypeOption type) { var process = Process.GetProcessById(processId); - var processTree = process.GetProcessTree(); + var processTree = process.GetProcessTree().Where(p => p.Process.ProcessName != "conhost" && p.Process.ProcessName != "WerFault").ToList(); if (processTree.Count > 1) { diff --git a/src/package/VSIXProject/TestPlatform.csproj b/src/package/VSIXProject/TestPlatform.csproj index a830fb53bd..ca48090d5c 100644 --- a/src/package/VSIXProject/TestPlatform.csproj +++ b/src/package/VSIXProject/TestPlatform.csproj @@ -238,6 +238,22 @@ + + + + + + + + + + + + + + + + diff --git a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs index 880e742290..7a036fdda3 100644 --- a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs @@ -172,7 +172,7 @@ public void InitializeWithDumpForHangShouldCaptureADumpOnTimeout() this.mockFileHelper.Setup(x => x.Exists(It.Is(y => y == "abc_hang.dmp"))).Returns(true); this.mockFileHelper.Setup(x => x.GetFullPath(It.Is(y => y == "abc_hang.dmp"))).Returns("abc_hang.dmp"); this.mockProcessDumpUtility.Setup(x => x.StartHangBasedProcessDump(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>())); - this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles()).Returns(new[] { dumpFile }); + this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles(true)).Returns(new[] { dumpFile }); this.mockDataCollectionSink.Setup(x => x.SendFileAsync(It.IsAny())).Callback(() => hangBasedDumpcollected.Set()); this.blameDataCollector.Initialize( @@ -184,7 +184,7 @@ public void InitializeWithDumpForHangShouldCaptureADumpOnTimeout() hangBasedDumpcollected.Wait(1000); this.mockProcessDumpUtility.Verify(x => x.StartHangBasedProcessDump(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>()), Times.Once); - this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(), Times.Once); + this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(true), Times.Once); this.mockDataCollectionSink.Verify(x => x.SendFileAsync(It.Is(y => y.Path == dumpFile)), Times.Once); } @@ -206,7 +206,7 @@ public void InitializeWithDumpForHangShouldCaptureKillTestHostOnTimeoutEvenIfGet this.mockFileHelper.Setup(x => x.Exists(It.Is(y => y == "abc_hang.dmp"))).Returns(true); this.mockFileHelper.Setup(x => x.GetFullPath(It.Is(y => y == "abc_hang.dmp"))).Returns("abc_hang.dmp"); this.mockProcessDumpUtility.Setup(x => x.StartHangBasedProcessDump(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>())); - this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles()).Callback(() => hangBasedDumpcollected.Set()).Throws(new Exception("Some exception")); + this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles(true)).Callback(() => hangBasedDumpcollected.Set()).Throws(new Exception("Some exception")); this.blameDataCollector.Initialize( this.GetDumpConfigurationElement(false, false, true, 0), @@ -217,7 +217,7 @@ public void InitializeWithDumpForHangShouldCaptureKillTestHostOnTimeoutEvenIfGet hangBasedDumpcollected.Wait(1000); this.mockProcessDumpUtility.Verify(x => x.StartHangBasedProcessDump(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>()), Times.Once); - this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(), Times.Once); + this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(true), Times.Once); } /// @@ -239,7 +239,7 @@ public void InitializeWithDumpForHangShouldCaptureKillTestHostOnTimeoutEvenIfAtt this.mockFileHelper.Setup(x => x.Exists(It.Is(y => y == "abc_hang.dmp"))).Returns(true); this.mockFileHelper.Setup(x => x.GetFullPath(It.Is(y => y == "abc_hang.dmp"))).Returns("abc_hang.dmp"); this.mockProcessDumpUtility.Setup(x => x.StartHangBasedProcessDump(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>())); - this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles()).Returns(new[] { dumpFile }); + this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles(true)).Returns(new[] { dumpFile }); this.mockDataCollectionSink.Setup(x => x.SendFileAsync(It.IsAny())).Callback(() => hangBasedDumpcollected.Set()).Throws(new Exception("Some other exception")); this.blameDataCollector.Initialize( @@ -251,7 +251,7 @@ public void InitializeWithDumpForHangShouldCaptureKillTestHostOnTimeoutEvenIfAtt hangBasedDumpcollected.Wait(1000); this.mockProcessDumpUtility.Verify(x => x.StartHangBasedProcessDump(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>()), Times.Once); - this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(), Times.Once); + this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(true), Times.Once); this.mockDataCollectionSink.Verify(x => x.SendFileAsync(It.Is(y => y.Path == dumpFile)), Times.Once); } @@ -366,7 +366,7 @@ public void TriggerSessionEndedHandlerShouldGetDumpFileIfProcDumpEnabled() this.context); // Setup - this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles()).Returns(new[] { this.filepath }); + this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles(It.IsAny())).Returns(new[] { this.filepath }); this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny>(), It.IsAny>(), It.IsAny())) .Returns(this.filepath); @@ -376,7 +376,7 @@ public void TriggerSessionEndedHandlerShouldGetDumpFileIfProcDumpEnabled() this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext)); // Verify GetDumpFiles Call - this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(), Times.Once); + this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(It.IsAny()), Times.Once); } /// @@ -418,7 +418,7 @@ public void TriggerSessionEndedHandlerShouldGetDumpFileIfCollectDumpOnExitIsEnab this.context); // Setup - this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles()).Returns(new[] { this.filepath }); + this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles(true)).Returns(new[] { this.filepath }); this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny>(), It.IsAny>(), It.IsAny())) .Returns(this.filepath); @@ -427,7 +427,7 @@ public void TriggerSessionEndedHandlerShouldGetDumpFileIfCollectDumpOnExitIsEnab this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext)); // Verify GetDumpFiles Call - this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(), Times.Once); + this.mockProcessDumpUtility.Verify(x => x.GetDumpFiles(true), Times.Once); } /// @@ -437,8 +437,10 @@ public void TriggerSessionEndedHandlerShouldGetDumpFileIfCollectDumpOnExitIsEnab public void TriggerSessionEndedHandlerShouldLogWarningIfGetDumpFileThrowsFileNotFound() { // Initializing Blame Data Collector + // force it to collect dump on exit, which won't happen and we should see a warning + // but we should not see warning if we tell it to create dump and there is no crash this.blameDataCollector.Initialize( - this.GetDumpConfigurationElement(), + this.GetDumpConfigurationElement(false, collectDumpOnExit: true), this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, this.mockLogger.Object, @@ -447,7 +449,7 @@ public void TriggerSessionEndedHandlerShouldLogWarningIfGetDumpFileThrowsFileNot // Setup and raise events this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny>(), It.IsAny>(), It.IsAny())) .Returns(this.filepath); - this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles()).Throws(new FileNotFoundException()); + this.mockProcessDumpUtility.Setup(x => x.GetDumpFiles(true)).Throws(new FileNotFoundException()); this.mockDataColectionEvents.Raise(x => x.TestHostLaunched += null, new TestHostLaunchedEventArgs(this.dataCollectionContext, 1234)); this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(new TestCase())); this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext)); @@ -605,6 +607,29 @@ public void TriggerTestHostLaunchedHandlerShouldLogWarningForNonBooleanCollectAl this.mockLogger.Verify(x => x.LogWarning(It.IsAny(), It.Is(str => str == string.Format(CultureInfo.CurrentUICulture, Resources.Resources.BlameParameterValueIncorrect, "DumpType", BlameDataCollector.Constants.FullConfigurationValue, BlameDataCollector.Constants.MiniConfigurationValue))), Times.Once); } + /// + /// The trigger test host launched handler should start process dump utility for full dump if full dump was enabled + /// + [TestMethod] + public void TriggerTestHostLaunchedHandlerShouldLogNoWarningWhenDumpTypeIsUsedWithHangDumpBecauseEitherHangDumpTypeOrDumpTypeCanBeSpecified() + { + var dumpConfig = this.GetDumpConfigurationElement(isFullDump: true, false, colectDumpOnHang: true, 1800000); + + // Initializing Blame Data Collector + this.blameDataCollector.Initialize( + dumpConfig, + this.mockDataColectionEvents.Object, + this.mockDataCollectionSink.Object, + this.mockLogger.Object, + this.context); + + // Raise TestHostLaunched + this.mockDataColectionEvents.Raise(x => x.TestHostLaunched += null, new TestHostLaunchedEventArgs(this.dataCollectionContext, 1234)); + + // Verify + this.mockLogger.Verify(x => x.LogWarning(It.IsAny(), It.IsAny()), Times.Never); + } + /// /// The trigger test host launched handler should not break if start process dump throws TestPlatFormExceptions and log error message /// diff --git a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs index a691cbe5dc..24566e7ab1 100644 --- a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs @@ -25,7 +25,14 @@ public class EnableBlameArgumentProcessorTests private Mock mockOutput; private TestableRunSettingsProvider settingsProvider; private EnableBlameArgumentExecutor executor; - private const string DefaultRunSettings = "\r\n\r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n "; + private string DefaultRunSettings = string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " "); public EnableBlameArgumentProcessorTests() { @@ -78,7 +85,28 @@ public void InitializeShouldCreateEntryForBlameInRunSettingsIfNotAlreadyPresent( this.executor.Initialize(""); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + "" + ), this.settingsProvider.ActiveRunSettings.SettingsXml); } [TestMethod] @@ -86,13 +114,56 @@ public void InitializeShouldOverwriteEntryForBlameInRunSettingsIfAlreadyPresent( { var runsettingsString = string.Format(DefaultRunSettings, ""); var runsettings = new RunSettings(); - runsettings.LoadSettingsXml("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n"); + runsettings.LoadSettingsXml(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + "")); this.settingsProvider.SetActiveRunSettings(runsettings); this.executor.Initialize("CollectDump;DumpType=full;CollectAlways=true"); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + ""), + this.settingsProvider.ActiveRunSettings.SettingsXml); } [TestMethod] @@ -118,7 +189,28 @@ public void InitializeShouldWarnIfPlatformNotSupportedForCollectDumpOption() this.mockOutput.Verify(x => x.WriteLine(CommandLineResources.BlameCollectDumpNotSupportedForPlatform, OutputLevel.Warning)); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + ""), + this.settingsProvider.ActiveRunSettings.SettingsXml); } } @@ -140,7 +232,28 @@ public void InitializeShouldWarnIfIncorrectParameterIsSpecifiedForCollectDumpOpt this.mockOutput.Verify(x => x.WriteLine(string.Format(CultureInfo.CurrentUICulture, CommandLineResources.BlameIncorrectOption, invalidParameter), OutputLevel.Warning)); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + ""), + this.settingsProvider.ActiveRunSettings.SettingsXml); } [TestMethod] @@ -162,7 +275,28 @@ public void InitializeShouldThrowIfInvalidParameterFormatIsSpecifiedForCollectDu this.mockOutput.Verify(x => x.WriteLine(string.Format(CultureInfo.CurrentUICulture, CommandLineResources.InvalidBlameArgument, invalidString), OutputLevel.Warning)); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + ""), + this.settingsProvider.ActiveRunSettings.SettingsXml); } [TestMethod] @@ -181,7 +315,29 @@ public void InitializeShouldCreateEntryForBlameAlongWithCollectDumpEntryIfEnable this.executor.Initialize("CollectDump"); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + ""), + this.settingsProvider.ActiveRunSettings.SettingsXml); } [TestMethod] @@ -200,7 +356,29 @@ public void InitializeShouldCreateEntryForBlameAlongWithCollectDumpParametersIfE this.executor.Initialize("CollectDump;DumpType=full;CollectAlways=true"); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + ""), + this.settingsProvider.ActiveRunSettings.SettingsXml); } [TestMethod] @@ -219,7 +397,71 @@ public void InitializeShouldCreateEntryForBlameAlongWithCollectHangDumpEntryIfEn this.executor.Initialize("CollectHangDump"); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual( + string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + ""), + this.settingsProvider.ActiveRunSettings.SettingsXml); + } + + [TestMethod] + public void InitializeShouldCreateEntryForBlameAlongWithCollectHangDumpParametersIfEnabled() + { + var runsettingsString = string.Format(DefaultRunSettings, ""); + var runsettings = new RunSettings(); + runsettings.LoadSettingsXml(DefaultRunSettings); + this.settingsProvider.SetActiveRunSettings(runsettings); + + this.mockEnvronment.Setup(x => x.OperatingSystem) + .Returns(PlatformOperatingSystem.Windows); + this.mockEnvronment.Setup(x => x.Architecture) + .Returns(PlatformArchitecture.X64); + + this.executor.Initialize("CollectHangDump;TestTimeout=10min;HangDumpType=Mini"); + + Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); + Assert.AreEqual(string.Join(Environment.NewLine, + "", + "", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + " C:\\dir\\TestResults", + " ", + " ", + " ", + " ", + " ", + " ", + ""), + this.settingsProvider.ActiveRunSettings.SettingsXml); } internal class TestableEnableBlameArgumentExecutor : EnableBlameArgumentExecutor