From d6ee1f4d0613b7d136eb403c8fcc172e28232e67 Mon Sep 17 00:00:00 2001 From: Vagisha Nidhi Date: Wed, 5 Jul 2017 01:51:41 -0700 Subject: [PATCH 1/9] Feature blame (#1) This feature gets the faulty test case name in event of a test host crash of reason unknown. There are various scenarios in which the test host crashes due to a faulty test case and the reason cannot be diagnosed. This pull request gets the name of the test case which caused the crash and displays it on the console. To enable the blame mode, use --Blame|/Blame --- TestPlatform.sln | 32 +++- scripts/build.ps1 | 7 + .../BlameCollector.cs | 122 +++++++++++++ .../BlameLogger.cs | 137 +++++++++++++++ .../Constants.cs | 61 +++++++ .../Interfaces/IBlameReaderWriter.cs | 25 +++ ...oft.TestPlatform.BlameDataCollector.csproj | 49 ++++++ .../XmlReaderWriter.cs | 93 ++++++++++ .../DesignMode/DesignModeClient.cs | 1 - src/Microsoft.TestPlatform.Common/Friends.cs | 1 + .../Logging/TestLoggerManager.cs | 1 - .../DataCollector/DataCollectionSink.cs | 2 +- src/vstest.console/Internal/ConsoleLogger.cs | 30 +++- .../EnableBlameArgumentProcessor.cs | 161 ++++++++++++++++++ .../Utilities/ArgumentProcessorFactory.cs | 3 +- .../Utilities/ArgumentProcessorPriority.cs | 5 + .../Utilities/HelpContentPriority.cs | 5 + .../Resources/Resources.Designer.cs | 12 ++ src/vstest.console/Resources/Resources.resx | 6 +- .../BlameCollectorTests.cs | 73 ++++++++ .../BlameLoggerTests.cs | 99 +++++++++++ ...atform.BlameDataCollector.UnitTests.csproj | 56 ++++++ .../XmlReaderWriterTests.cs | 91 ++++++++++ .../CollectArgumentProcessorTests.cs | 2 +- .../EnableBlameArgumentProcessorTests.cs | 69 ++++++++ 25 files changed, 1128 insertions(+), 15 deletions(-) create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs create mode 100644 src/vstest.console/Processors/EnableBlameArgumentProcessor.cs create mode 100644 test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs create mode 100644 test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs create mode 100644 test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj create mode 100644 test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs create mode 100644 test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs diff --git a/TestPlatform.sln b/TestPlatform.sln index 2553cb8a81..8b0d572886 100644 --- a/TestPlatform.sln +++ b/TestPlatform.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26326.0 +VisualStudioVersion = 15.0.26605.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED0C35EB-7F31-4841-A24F-8EB708FFA959}" EndProject @@ -151,6 +151,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.TestHostProvider", "src\Microsoft.TestPlatform.TestHostProvider\Microsoft.TestPlatform.TestHostProvider.csproj", "{11ECCB8B-6958-42A7-BD58-88C09CB149B2}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.BlameDataCollector", "src\Microsoft.TestPlatform.BlameDataCollector\Microsoft.TestPlatform.BlameDataCollector.csproj", "{76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.BlameDataCollector.UnitTests", "test\Microsoft.TestPlatform.BlameDataCollector.UnitTests\Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj", "{67AEC962-14ED-4432-86BF-14F3381D2B2F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -785,6 +789,30 @@ Global {11ECCB8B-6958-42A7-BD58-88C09CB149B2}.Release|x64.Build.0 = Release|Any CPU {11ECCB8B-6958-42A7-BD58-88C09CB149B2}.Release|x86.ActiveCfg = Release|Any CPU {11ECCB8B-6958-42A7-BD58-88C09CB149B2}.Release|x86.Build.0 = Release|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Debug|x64.ActiveCfg = Debug|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Debug|x64.Build.0 = Debug|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Debug|x86.ActiveCfg = Debug|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Debug|x86.Build.0 = Debug|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|Any CPU.Build.0 = Release|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|x64.ActiveCfg = Release|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|x64.Build.0 = Release|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|x86.ActiveCfg = Release|Any CPU + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|x86.Build.0 = Release|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|x64.ActiveCfg = Debug|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|x64.Build.0 = Debug|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|x86.ActiveCfg = Debug|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|x86.Build.0 = Debug|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|Any CPU.Build.0 = Release|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|x64.ActiveCfg = Release|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|x64.Build.0 = Release|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|x86.ActiveCfg = Release|Any CPU + {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -851,5 +879,7 @@ Global {7B48115A-B766-4B55-93A8-C08A42C37710} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {FBF74C8F-695C-4967-84AC-358EEFB1376D} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {11ECCB8B-6958-42A7-BD58-88C09CB149B2} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} + {67AEC962-14ED-4432-86BF-14F3381D2B2F} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} EndGlobalSection EndGlobal diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 3d86d749f4..c4032406a4 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -266,6 +266,13 @@ function Publish-Package Write-Verbose "Move-Item $coreCLR20PackageDir\$file $coreCLRExtensionsDir -Force" Move-Item $coreCLR20PackageDir\$file $coreCLRExtensionsDir -Force } + + # Publish Datacollector + $blameDataCollector = Join-Path $env:TP_ROOT_DIR "src\Microsoft.TestPlatform.BlameDataCollector\bin\$TPB_Configuration" + $blameDataCollectorNet46 = Join-Path $blameDataCollector $TPB_TargetFramework + $blameDataCollectorNetCore = Join-Path $blameDataCollector $TPB_TargetFrameworkCore + Copy-Item $blameDataCollectorNet46\* $fullCLRExtensionsDir -Force + Copy-Item $blameDataCollectorNetCore\* $coreCLRExtensionsDir -Force # Note Note: If there are some dependencies for the TestHostRuntimeProvider assemblies, those need to be moved too. $runtimeproviders = @("Microsoft.TestPlatform.TestHostRuntimeProvider.dll", "Microsoft.TestPlatform.TestHostRuntimeProvider.pdb") diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs b/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs new file mode 100644 index 0000000000..6f5186a5fd --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs @@ -0,0 +1,122 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.TestPlatform.BlameDataCollector +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Xml; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + + [DataCollectorFriendlyName("Blame")] + [DataCollectorTypeUri("datacollector://microsoft/blame/1.0")] + public class BlameCollector : DataCollector, ITestExecutionEnvironmentSpecifier + { + private DataCollectionSink dataCollectionSink; + private DataCollectionEnvironmentContext context; + private DataCollectionEvents events; + private List testSequence; + private IBlameReaderWriter blameReaderWriter; + private int testStartCount; + private int testEndCount; + + /// + /// Initializes a new instance of the class. + /// Using XmlReaderWriter by default + /// + public BlameCollector() + : this(new XmlReaderWriter()) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// BlameReaderWriter instance. + public BlameCollector(IBlameReaderWriter blameReaderWriter) + { + this.blameReaderWriter = blameReaderWriter; + } + + /// + /// Gets environment variables that should be set in the test execution environment + /// + /// Environment variables that should be set in the test execution environment + public IEnumerable> GetTestExecutionEnvironmentVariables() + { + return new List> { }; + } + + /// + /// Initializes parameters for the new instance of the class + /// + /// The Xml Element to save to + /// Data collection events to which methods subscribe + /// A data collection sink for data transfer + /// Data Collection Logger to send messages to the client + /// Context of data collector environment + public override void Initialize(XmlElement configurationElement, + DataCollectionEvents events, DataCollectionSink dataSink, + DataCollectionLogger logger, DataCollectionEnvironmentContext environmentContext) + { + ValidateArg.NotNull(logger, nameof(logger)); + + this.events = events; + this.dataCollectionSink = dataSink; + this.context = environmentContext; + testSequence = new List(); + + // Subscribing to events + this.events.SessionEnd += this.SessionEnded_Handler; + this.events.TestCaseStart += this.Events_TestCaseStart; + this.events.TestCaseEnd += this.Events_TestCaseEnd; + } + + /// + /// Called when Test Case Start event is invoked + /// + private void Events_TestCaseStart(object sender, TestCaseStartEventArgs e) + { + EqtTrace.Info("Blame Collector : " + Constants.TestCaseStart); + TestCase testcase = new TestCase(e.TestElement.FullyQualifiedName, e.TestElement.ExecutorUri, e.TestElement.Source); + this.testSequence.Add(testcase); + this.testStartCount++; + } + + /// + /// Called when Test Case End event is invoked + /// + private void Events_TestCaseEnd(object sender, TestCaseEndEventArgs e) + { + EqtTrace.Info("Blame Collector : " + Constants.TestCaseEnd); + this.testEndCount++; + } + + /// + /// Called when Session End event is invoked + /// + private void SessionEnded_Handler(object sender, SessionEndEventArgs args) + { + EqtTrace.Info("Blame Collector :" + Constants.TestSessionEnd); + if (this.testStartCount != this.testEndCount) + { + var filepath = Path.Combine(AppContext.BaseDirectory, Constants.AttachmentFileName); + this.blameReaderWriter.WriteTestSequence(this.testSequence, filepath); + this.dataCollectionSink.SendFileAsync(this.context.SessionDataCollectionContext, filepath, true); + } + DeregisterEvents(); + } + + /// + /// Method to deregister handlers and cleanup + /// + private void DeregisterEvents() + { + this.events.SessionEnd -= this.SessionEnded_Handler; + this.events.TestCaseStart -= this.Events_TestCaseStart; + this.events.TestCaseEnd -= this.Events_TestCaseEnd; + } + } +} diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs b/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs new file mode 100644 index 0000000000..1baa8516d4 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.TestPlatform.BlameDataCollector +{ + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.Utilities; + using System; + using System.Collections.Generic; + using System.Globalization; + + [FriendlyName(BlameLogger.FriendlyName)] + [ExtensionUri(BlameLogger.ExtensionUri)] + public class BlameLogger : ITestLogger + { + private readonly IBlameReaderWriter blameReaderWriter; + + #region Constants + + /// + /// Uri used to uniquely identify the Blame logger. + /// + public const string ExtensionUri = "logger://Microsoft/TestPlatform/BlameLogger"; + + /// + /// Alternate user friendly string to uniquely identify the Blame logger. + /// + public const string FriendlyName = "Blame"; + + #endregion + + #region Constructor + + /// + /// Constructor : Default BlameReaderWriter used is XmlReaderWriter + /// + public BlameLogger() + : this(ConsoleOutput.Instance, new XmlReaderWriter()) + { + } + + /// + /// Constructor added for testing purpose + /// + /// + /// BlameReaderWriter Instance + public BlameLogger(IOutput output, IBlameReaderWriter blameReaderWriter) + { + this.Output = output; + this.blameReaderWriter = blameReaderWriter; + } + + protected IOutput Output + { + get; + private set; + } + + #endregion + + #region ITestLogger + + /// + /// Initializes the Logger. + /// + /// Events that can be registered for. + /// Test Run Directory + public void Initialize(TestLoggerEvents events, string testRunDictionary) + { + if (events == null) + { + throw new ArgumentNullException(nameof(events)); + } + events.TestRunComplete += this.TestRunCompleteHandler; + } + + /// + /// Called when a test run is complete. + /// + private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) + { + ValidateArg.NotNull(sender, "sender"); + ValidateArg.NotNull(e, "e"); + + if (!e.IsAborted) return; + + Output.WriteLine(string.Empty, OutputLevel.Information); + + // Gets the faulty test case if test aborted + var testCaseName = GetFaultyTestCase(e); + string reason = Constants.TestRunAbortReason + testCaseName; + Output.Error(reason); + } + + #endregion + + #region Faulty test case fetch + + /// + /// Fetches faulty test case + /// + private string GetFaultyTestCase(TestRunCompleteEventArgs e) + { + string testname = null; + foreach (var attachmentSet in e.AttachmentSets) + { + if (attachmentSet.DisplayName.Equals(Constants.BlameDataCollectorName)) + { + testname = GetLastTestFromFile(attachmentSet.Attachments[0].Uri.LocalPath); + break; + } + } + return testname; + } + + /// + /// Reads file for last test case + /// + public string GetLastTestFromFile(string filepath) + { + try + { + List testCaseList = this.blameReaderWriter.ReadTestSequence(filepath); + var testcase = testCaseList[testCaseList.Count - 1]; + return testcase.FullyQualifiedName; + } + catch (NullReferenceException e) + { + EqtTrace.Error("Blame Logger: GetLastTestFromFile : " + e); + } + return String.Empty; + } + + #endregion + } +} diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs b/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs new file mode 100644 index 0000000000..4380d6e023 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.TestPlatform.BlameDataCollector +{ + /// + /// Class for constants used across the files. + /// + internal static class Constants + { + /// + /// The test session end constant. + /// + public const string TestSessionEnd = "TestSessionEnd"; + + /// + /// The test case start constant. + /// + public const string TestCaseStart = "TestCaseStart"; + + /// + /// The test case end constant. + /// + public const string TestCaseEnd = "TestCaseEnd"; + + /// + /// Root node name for Xml file. + /// + public const string BlameRootNode = "TestSequence"; + + /// + /// Node name for each Xml node. + /// + public const string BlameTestNode = "Test"; + + /// + /// Attachment File name. + /// + public const string AttachmentFileName = "TestSequence.xml"; + + /// + /// Test Name Attribute. + /// + public const string TestNameAttribute = "Name"; + + /// + /// Test Source Attribute. + /// + public const string TestSourceAttribute = "Source"; + + /// + /// Friendly name of the data collector + /// + public const string BlameDataCollectorName = "Blame"; + + /// + /// Test run Abort + /// + public const string TestRunAbortReason = "The test run was aborted because the host process crashed unexpectedly while executing test "; + } +} diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs b/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs new file mode 100644 index 0000000000..8e094fb7aa --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.TestPlatform.BlameDataCollector +{ + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using System.Collections.Generic; + + public interface IBlameReaderWriter + { + /// + /// Writes tests to document + /// + /// List of tests in sequence + /// The path of file + void WriteTestSequence(List testSequence, string filePath); + + /// + /// Reads all tests from file + /// + /// The path of saved file + /// All tests + List ReadTestSequence(string filePath); + } +} diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj b/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj new file mode 100644 index 0000000000..1119fef0a7 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj @@ -0,0 +1,49 @@ + + + + ..\..\ + + + + Microsoft.TestPlatform.BlameDataCollector + + + Microsoft.TestPlatform.BlameDataCollector + netcoreapp1.0;netcoreapp2.0;net46 + true + $(PackageTargetFallback);dnxcore50;netstandardapp1.0;portable-net45+win8;portable-net45+wp80+win8+wpa81+dnxcore50 + AnyCPU + + + + + + + + + true + + + true + + + + + 4.3.0 + + + + + 4.3.0 + + + 4.3.0 + + + + + + + + + diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs b/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs new file mode 100644 index 0000000000..a5d6969021 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.TestPlatform.BlameDataCollector +{ + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; + using System.Collections.Generic; + using System.IO; + using System.Xml; + + /// + /// XmlReaderWriter class for reading and writing test sequences to file + /// + public class XmlReaderWriter : IBlameReaderWriter + { + private readonly IFileHelper fileHelper; + + #region Constructor + + public XmlReaderWriter() + : this(new FileHelper()) + { } + + public XmlReaderWriter(IFileHelper fileHelper) + { + this.fileHelper = fileHelper; + } + + #endregion + + /// + /// Adds tests to document and saves document to file + /// + public void WriteTestSequence(List testSequence, string filePath) + { + ValidateArg.NotNull(testSequence, nameof(testSequence)); + ValidateArg.NotNullOrEmpty(filePath, nameof(filePath)); + + var xmlDocument = new XmlDocument(); + var xmlDeclaration = xmlDocument.CreateNode(XmlNodeType.XmlDeclaration, string.Empty, string.Empty); + var blameTestRoot = xmlDocument.CreateElement(Constants.BlameRootNode); + xmlDocument.AppendChild(xmlDeclaration); + + foreach (var testCase in testSequence) + { + var testElement = xmlDocument.CreateElement(Constants.BlameTestNode); + testElement.SetAttribute(Constants.TestNameAttribute, testCase.FullyQualifiedName); + testElement.SetAttribute(Constants.TestSourceAttribute, testCase.Source); + blameTestRoot.AppendChild(testElement); + } + xmlDocument.AppendChild(blameTestRoot); + + using (var stream = this.fileHelper.GetStream(filePath, FileMode.Create)) + { + xmlDocument.Save(stream); + } + } + + /// + /// Reads All test case from file + /// + /// The path of saved file + /// Test Case List + public List ReadTestSequence(string filePath) + { + ValidateArg.NotNullOrEmpty(filePath, nameof(filePath)); + + if (!fileHelper.Exists(filePath)) + { + throw new FileNotFoundException(); + } + + List testCaseList = new List(); + var xmlDocument = new XmlDocument(); + using (var stream = this.fileHelper.GetStream(filePath, FileMode.Open)) + { + xmlDocument.Load(stream); + } + var root = xmlDocument.LastChild; + + foreach (XmlNode node in root) + { + TestCase testCase = new TestCase(); + testCase.FullyQualifiedName = node.Attributes[Constants.TestNameAttribute].Value; + testCase.Source = node.Attributes[Constants.TestSourceAttribute].Value; + testCaseList.Add(testCase); + } + return testCaseList; + } + } +} diff --git a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs index 25d279a652..df3350d09f 100644 --- a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs +++ b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs @@ -147,7 +147,6 @@ private void ProcessRequests(ITestRequestManager testRequestManager) case MessageType.StartDiscovery: { - var discoveryPayload = this.dataSerializer.DeserializePayload(message); this.StartDiscovery(discoveryPayload, testRequestManager); break; diff --git a/src/Microsoft.TestPlatform.Common/Friends.cs b/src/Microsoft.TestPlatform.Common/Friends.cs index 1655273bda..430177d5fc 100644 --- a/src/Microsoft.TestPlatform.Common/Friends.cs +++ b/src/Microsoft.TestPlatform.Common/Friends.cs @@ -22,5 +22,6 @@ [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] [assembly: InternalsVisibleTo("Microsoft.TestPlatform.CommunicationUtilities.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.TestPlatform.Client.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("Microsoft.TestPlatform.BlameDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] #endregion \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Logging/TestLoggerManager.cs b/src/Microsoft.TestPlatform.Common/Logging/TestLoggerManager.cs index c33b2c9100..f81a326cee 100644 --- a/src/Microsoft.TestPlatform.Common/Logging/TestLoggerManager.cs +++ b/src/Microsoft.TestPlatform.Common/Logging/TestLoggerManager.cs @@ -18,7 +18,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.Logging using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using CommonResources = Microsoft.VisualStudio.TestPlatform.Common.Resources.Resources; - using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework; /// /// Responsible for managing logger extensions and broadcasting results diff --git a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/DataCollectionSink.cs b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/DataCollectionSink.cs index 0ba739b967..944f4a6959 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/DataCollectionSink.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/DataCollectionSink.cs @@ -39,7 +39,7 @@ protected DataCollectionSink() /// The context in which the file is being sent. Cannot be null. /// the path to the file on the local file system /// True to automatically have the file removed after sending it. - public void SendFileAsync(DataCollectionContext context, string path, bool deleteFile) + public virtual void SendFileAsync(DataCollectionContext context, string path, bool deleteFile) { this.SendFileAsync(context, path, string.Empty, deleteFile); } diff --git a/src/vstest.console/Internal/ConsoleLogger.cs b/src/vstest.console/Internal/ConsoleLogger.cs index 4174183fb3..ad9d5e13b1 100644 --- a/src/vstest.console/Internal/ConsoleLogger.cs +++ b/src/vstest.console/Internal/ConsoleLogger.cs @@ -17,7 +17,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Internal using Microsoft.VisualStudio.TestPlatform.Utilities; using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; - + /// /// Logger for sending output to the console. /// All the console logger messages prints to Standard Output with respective color, except OutputLevel.Error messages @@ -30,6 +30,8 @@ internal class ConsoleLogger : ITestLoggerWithParameters #region Constants private const string TestMessageFormattingPrefix = " "; + private const string BlameDataCollectorName = "Blame"; + /// /// Uri used to uniquely identify the console logger. /// @@ -390,18 +392,31 @@ private void TestResultHandler(object sender, TestResultEventArgs e) private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) { Output.WriteLine(string.Empty, OutputLevel.Information); - - // Printing Run-level Attachments var runLevelAttachementCount = (e.AttachmentSets == null) ? 0 : e.AttachmentSets.Sum(attachmentSet => attachmentSet.Attachments.Count); + + // Printing Run-level Attachments + if (runLevelAttachementCount > 0) + { + foreach (var attachmentSet in e.AttachmentSets) + { + if (!attachmentSet.DisplayName.Equals(BlameDataCollectorName)) + { + Output.Information(CommandLineResources.AttachmentsBanner); + break; + } + } + } if (runLevelAttachementCount > 0) { - Output.Information(CommandLineResources.AttachmentsBanner); foreach (var attachmentSet in e.AttachmentSets) { - foreach (var uriDataAttachment in attachmentSet.Attachments) + if (!attachmentSet.DisplayName.Equals(BlameDataCollectorName)) { - var attachmentOutput = string.Format(CultureInfo.CurrentCulture, CommandLineResources.AttachmentOutputFormat, uriDataAttachment.Uri.LocalPath); - Output.Information(attachmentOutput); + foreach (var uriDataAttachment in attachmentSet.Attachments) + { + var attachmentOutput = string.Format(CultureInfo.CurrentCulture, CommandLineResources.AttachmentOutputFormat, uriDataAttachment.Uri.LocalPath); + Output.Information(attachmentOutput); + } } } Output.WriteLine(String.Empty, OutputLevel.Information); @@ -432,6 +447,5 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) } } #endregion - } } diff --git a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs new file mode 100644 index 0000000000..87b219e5c4 --- /dev/null +++ b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs @@ -0,0 +1,161 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors +{ + using System; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; + using Microsoft.VisualStudio.TestPlatform.Common.Interfaces; + using Microsoft.VisualStudio.TestPlatform.Common.Logging; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using Microsoft.VisualStudio.TestPlatform.Common; + using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + + internal class EnableBlameArgumentProcessor : IArgumentProcessor + { + /// + /// The name of the command line argument that the ListTestsArgumentExecutor handles. + /// + public const string CommandName = "/Blame"; + + private Lazy metadata; + + private Lazy executor; + + /// + /// Initializes a new instance of the class. + /// + public EnableBlameArgumentProcessor() + { + } + + public Lazy Metadata + { + get + { + if (this.metadata == null) + { + this.metadata = new Lazy(() => new EnableBlameArgumentProcessorCapabilities()); + } + + return this.metadata; + } + } + + /// + /// Gets or sets the executor. + /// + public Lazy Executor + { + get + { + if (this.executor == null) + { + this.executor = new Lazy(() => new EnableBlameArgumentExecutor(RunSettingsManager.Instance, TestLoggerManager.Instance)); + } + + return this.executor; + } + set + { + this.executor = value; + } + } + } + + /// + /// The argument capabilities. + /// + internal class EnableBlameArgumentProcessorCapabilities : BaseArgumentProcessorCapabilities + { + public override string CommandName => EnableBlameArgumentProcessor.CommandName; + + public override bool AllowMultiple => false; + + public override bool IsAction => false; + + public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.Blame; + + public override string HelpContentResourceName => CommandLineResources.EnableBlameUsage; + + public override HelpContentPriority HelpPriority => HelpContentPriority.EnableBlameArgumentProcessorHelpPriority; + } + + /// + /// The argument executor. + /// + internal class EnableBlameArgumentExecutor : IArgumentExecutor + { + /// + /// Blame logger and data collector friendly name + /// + private static string BlameFriendlyName = "Blame"; + + /// + /// Test logger manager instance + /// + private readonly TestLoggerManager loggerManager; + + /// + /// Run settings manager + /// + private IRunSettingsProvider runSettingsManager; + + #region Constructor + + internal EnableBlameArgumentExecutor(IRunSettingsProvider runSettingsManager, TestLoggerManager loggerManager) + { + Contract.Requires(loggerManager != null); + + this.runSettingsManager = runSettingsManager; + this.loggerManager = loggerManager; + } + #endregion + + #region IArgumentExecutor + + /// + /// Initializes with the argument that was provided with the command. + /// + /// Argument that was provided with the command. + public void Initialize(string argument) + { + // Add Blame Logger + this.loggerManager.UpdateLoggerList(BlameFriendlyName.ToLower(), BlameFriendlyName.ToLower(), null); + + // Add Blame Data Collector + CollectArgumentExecutor.EnabledDataCollectors.Add(BlameFriendlyName.ToLower()); + + var settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml; + if (settings == null) + { + this.runSettingsManager.AddDefaultRunSettings(); + settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml; + } + + var dataCollectionRunSettings = XmlRunSettingsUtilities.GetDataCollectionRunSettings(settings); + if (dataCollectionRunSettings == null) + { + dataCollectionRunSettings = new DataCollectionRunSettings(); + } + + CollectArgumentExecutor.EnableDataCollectorUsingFriendlyName(BlameFriendlyName, dataCollectionRunSettings); + this.runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.DataCollectionRunSettingsName, dataCollectionRunSettings.ToXml().InnerXml); + } + + /// + /// Executes the argument processor. + /// + /// The . + public ArgumentProcessorResult Execute() + { + // Nothing to do since we updated the logger and data collector list in initialize + return ArgumentProcessorResult.Success; + } + + #endregion + } +} diff --git a/src/vstest.console/Processors/Utilities/ArgumentProcessorFactory.cs b/src/vstest.console/Processors/Utilities/ArgumentProcessorFactory.cs index 0a7db269f6..f59370e320 100644 --- a/src/vstest.console/Processors/Utilities/ArgumentProcessorFactory.cs +++ b/src/vstest.console/Processors/Utilities/ArgumentProcessorFactory.cs @@ -234,7 +234,8 @@ public IEnumerable GetArgumentProcessorsToAlwaysExecute() new InIsolationArgumentProcessor(), new CollectArgumentProcessor(), new EnableCodeCoverageArgumentProcessor(), - new DisableAutoFakesArgumentProcessor() + new DisableAutoFakesArgumentProcessor(), + new EnableBlameArgumentProcessor() }; /// diff --git a/src/vstest.console/Processors/Utilities/ArgumentProcessorPriority.cs b/src/vstest.console/Processors/Utilities/ArgumentProcessorPriority.cs index b54592761e..6893c50b12 100644 --- a/src/vstest.console/Processors/Utilities/ArgumentProcessorPriority.cs +++ b/src/vstest.console/Processors/Utilities/ArgumentProcessorPriority.cs @@ -23,6 +23,11 @@ internal enum ArgumentProcessorPriority /// Diag = 1, + /// + /// Priority of the Blame processor. + /// + Blame = 1, + /// /// Priority of processors related to design mode. This needs to be higher priority /// since some of the functionalities (like logger) depend on this. diff --git a/src/vstest.console/Processors/Utilities/HelpContentPriority.cs b/src/vstest.console/Processors/Utilities/HelpContentPriority.cs index 53c716518e..b8ba2b078e 100644 --- a/src/vstest.console/Processors/Utilities/HelpContentPriority.cs +++ b/src/vstest.console/Processors/Utilities/HelpContentPriority.cs @@ -97,6 +97,11 @@ internal enum HelpContentPriority /// EnableDiagArgumentProcessorHelpPriority, + /// + /// EnableBlameArgumentProcessor Help + /// + EnableBlameArgumentProcessorHelpPriority, + /// /// EnableLoggerArgumentProcessor Help /// diff --git a/src/vstest.console/Resources/Resources.Designer.cs b/src/vstest.console/Resources/Resources.Designer.cs index 101f81b179..099108bb6f 100644 --- a/src/vstest.console/Resources/Resources.Designer.cs +++ b/src/vstest.console/Resources/Resources.Designer.cs @@ -475,6 +475,18 @@ public static string EnableDiagUsage } } + /// + /// Looks up a localized string similar to --Blame|/Blame + /// Enable Blame mode for diagnosis of faulty test case + /// + public static string EnableBlameUsage + { + get + { + return ResourceManager.GetString("EnableBlameUsage", resourceCulture); + } + } + /// /// Looks up a localized string similar to --logger|/logger:<Logger Uri/FriendlyName> /// Specify a logger for test results. For example, to log results into a diff --git a/src/vstest.console/Resources/Resources.resx b/src/vstest.console/Resources/Resources.resx index ca40f7e946..58c77b4b0d 100644 --- a/src/vstest.console/Resources/Resources.resx +++ b/src/vstest.console/Resources/Resources.resx @@ -655,4 +655,8 @@ Debug Traces Messages: - \ No newline at end of file + + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs new file mode 100644 index 0000000000..5457379e5e --- /dev/null +++ b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests +{ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; + using Moq; + using Microsoft.TestPlatform.BlameDataCollector; + using System.Xml; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using System.IO; + using System.Collections.Generic; + + [TestClass] + public class BlameCollectorTests + { + private DataCollectionEnvironmentContext context; + private DataCollectionContext dataCollectionContext; + private BlameCollector blameDataCollector; + private Mock mockLogger; + private Mock mockDataColectionEvents; + private Mock mockDataCollectionSink; + private Mock mockBlameReaderWriter; + private XmlElement configurationElement; + + public BlameCollectorTests() + { + // Initializing mocks + this.mockLogger = new Mock(); + this.mockDataColectionEvents = new Mock(); + this.mockDataCollectionSink = new Mock(); + this.mockBlameReaderWriter = new Mock(); + this.blameDataCollector = new BlameCollector(this.mockBlameReaderWriter.Object); + + // Initializing members + TestCase testcase = new TestCase(); + testcase.Id = Guid.NewGuid(); + this.dataCollectionContext = new DataCollectionContext(testcase); + this.configurationElement = null; + this.context = new DataCollectionEnvironmentContext(this.dataCollectionContext); + } + + [TestMethod] + public void InitializeShouldThrowExceptionIfDataCollectionLoggerIsNull() + { + Assert.ThrowsException(() => + { + this.blameDataCollector.Initialize(this.configurationElement, + this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, + (DataCollectionLogger)null, null); + }); + } + + [TestMethod] + public void TriggerSessionEndedHandlerShouldWriteToFile() + { + // Initializing Blame Data Collector + this.blameDataCollector.Initialize(this.configurationElement, + this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, + this.mockLogger.Object, this.context); + var filepath = Path.Combine(AppContext.BaseDirectory, "TestSequence.xml"); + + // Setup and Raise Session End Event + this.mockDataCollectionSink.Setup(x => x.SendFileAsync(It.IsAny(), It.IsAny(), It.IsAny())); + this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(dataCollectionContext)); + + // Verify WriteTestSequence Call + this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), filepath), Times.Once); + } + } +} diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs new file mode 100644 index 0000000000..57369f3f79 --- /dev/null +++ b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Microsoft.TestPlatform.BlameDataCollector; + using System; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Moq; + using Microsoft.VisualStudio.TestPlatform.Utilities; + using Microsoft.VisualStudio.TestPlatform.Common.Logging; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using System.Collections.Generic; + using System.Collections.ObjectModel; + + [TestClass] + public class BlameLoggerTests + { + private Mock testRunRequest; + private Mock events; + private Mock mockOutput; + private Mock mockBlameReaderWriter; + private TestLoggerManager testLoggerManager; + private BlameLogger blameLogger; + + + public BlameLoggerTests() + { + // Mock for ITestRunRequest + this.testRunRequest = new Mock(); + this.events = new Mock(); + this.mockOutput = new Mock(); + this.mockBlameReaderWriter = new Mock(); + this.blameLogger = new BlameLogger(this.mockOutput.Object, mockBlameReaderWriter.Object); + + // Create Instance of TestLoggerManager + this.testLoggerManager = new DummyTestLoggerManager(); + this.testLoggerManager.AddLogger(this.blameLogger, BlameLogger.ExtensionUri, null); + this.testLoggerManager.EnableLogging(); + + // Register TestRunRequest object + this.testLoggerManager.RegisterTestRunEvents(this.testRunRequest.Object); + } + + [TestMethod] + public void InitializeShouldThrowExceptionIfEventsIsNull() + { + Assert.ThrowsException(() => + { + this.blameLogger.Initialize(null, string.Empty); + }); + } + + [TestMethod] + public void TestResulCompleteHandlerShouldThowExceptionIfEventArgsIsNull() + { + // Raise an event on mock object + Assert.ThrowsException(() => + { + this.testRunRequest.Raise(m => m.OnRunCompletion += null, default(TestRunCompleteEventArgs)); + }); + } + + [TestMethod] + public void TestRunCompleteHandlerShouldGetFaultyTestCaseIfTestRunAborted() + { + // Initialize + var attachmentSet = new AttachmentSet(new Uri("test://uri"), "Blame"); + var uriDataAttachment = new UriDataAttachment(new Uri("C:/folder1/sequence.xml"), "description"); + attachmentSet.Attachments.Add(uriDataAttachment); + var attachmentSetList = new List(); + attachmentSetList.Add(attachmentSet); + + // Initialize Blame Logger + this.blameLogger.Initialize(this.events.Object, null); + + List testCaseList = new List(); + testCaseList.Add(new TestCase("ABC.UnitTestMethod1", new Uri("test://uri"), "C://test/filepath")); + testCaseList.Add(new TestCase("ABC.UnitTestMethod2", new Uri("test://uri"), "C://test/filepath")); + + // Setup and Raise event + this.mockBlameReaderWriter.Setup(x => x.ReadTestSequence(It.IsAny())).Returns(testCaseList); + this.testRunRequest.Raise( + m => m.OnRunCompletion += null, + new TestRunCompleteEventArgs(stats: null, isCanceled: false, isAborted: true, error: null, attachmentSets: new Collection(attachmentSetList), elapsedTime: new TimeSpan(1, 0, 0, 0))); + + // Verify Call + this.mockBlameReaderWriter.Verify(x => x.ReadTestSequence(It.IsAny()), Times.Once); + } + + internal class DummyTestLoggerManager : TestLoggerManager + { + public DummyTestLoggerManager() : base(TestSessionMessageLogger.Instance, new InternalTestLoggerEvents(TestSessionMessageLogger.Instance)) + { + } + } + } +} diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj new file mode 100644 index 0000000000..7d98632a5d --- /dev/null +++ b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj @@ -0,0 +1,56 @@ + + + + ..\..\ + true + + + + Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests + + + netcoreapp1.0;net46 + Microsoft.TestPlatform.BlameDataCollector.UnitTests + $(PackageTargetFallback);dnxcore50;portable-net45+win8 + + + + + + + true + + + true + + + true + + + true + + + true + + + + + + + + + + + + + 4.3.0 + + + + + + + + + + diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs new file mode 100644 index 0000000000..2f60ebf4be --- /dev/null +++ b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests +{ + using System; + using System.Collections.Generic; + using Microsoft.TestPlatform.BlameDataCollector; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; + + [TestClass] + public class XmlReaderWriterTests + { + private XmlReaderWriter xmlReaderWriter; + private Mock mockFileHelper; + + public XmlReaderWriterTests() + { + this.mockFileHelper = new Mock(); + this.xmlReaderWriter = new XmlReaderWriter(this.mockFileHelper.Object); + } + + [TestMethod] + public void WriteTestSequenceShouldThrowExceptionIfFilePathIsNull() + { + TestCase testcase = new TestCase + { + Id = Guid.NewGuid(), + FullyQualifiedName = "TestProject.UnitTest.TestMethod", + Source = "abc.dll" + }; + List testSequence = new List(); + testSequence.Add(testcase); + + Assert.ThrowsException(() => + { + this.xmlReaderWriter.WriteTestSequence(testSequence, null); + }); + } + + [TestMethod] + public void WriteTestSequenceShouldThrowExceptionIfFilePathIsEmpty() + { + TestCase testcase = new TestCase + { + Id = Guid.NewGuid(), + FullyQualifiedName = "TestProject.UnitTest.TestMethod", + Source = "abc.dll" + }; + List testSequence = new List(); + testSequence.Add(testcase); + + Assert.ThrowsException(() => + { + this.xmlReaderWriter.WriteTestSequence(testSequence, String.Empty); + }); + } + + [TestMethod] + public void ReadTestSequenceShouldThrowExceptionIfFilePathIsNull() + { + Assert.ThrowsException(() => + { + this.xmlReaderWriter.ReadTestSequence(null); + }); + } + + [TestMethod] + public void ReadTestSequenceShouldThrowExceptionIfFilePathIsEmpty() + { + Assert.ThrowsException(() => + { + this.xmlReaderWriter.ReadTestSequence(String.Empty); + }); + } + + [TestMethod] + public void ReadTestSequenceShouldThrowExceptionIfFileNotFound() + { + this.mockFileHelper.Setup(m => m.Exists(It.IsAny())).Returns(false); + + Assert.ThrowsException(() => + { + this.xmlReaderWriter.ReadTestSequence(String.Empty); + }); + } + } +} diff --git a/test/vstest.console.UnitTests/Processors/CollectArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/CollectArgumentProcessorTests.cs index 696c7b260f..72217d0ee0 100644 --- a/test/vstest.console.UnitTests/Processors/CollectArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/CollectArgumentProcessorTests.cs @@ -132,7 +132,7 @@ public void InitializeShouldEnableMultipleCollectorsWhenCalledMoreThanOnce() Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); } - + #endregion } } diff --git a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs new file mode 100644 index 0000000000..7e204f8f5c --- /dev/null +++ b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace vstest.console.UnitTests.Processors +{ + using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors; + using Microsoft.VisualStudio.TestPlatform.Common; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using vstest.console.UnitTests.TestDoubles; + + [TestClass] + public class EnableBlameArgumentProcessorTests + { + private TestableRunSettingsProvider settingsProvider; + private EnableBlameArgumentExecutor executor; + private DummyTestLoggerManager testloggerManager; + private const string DefaultRunSettings = "\r\n\r\n \r\n {0}\r\n \r\n"; + + public EnableBlameArgumentProcessorTests() + { + this.settingsProvider = new TestableRunSettingsProvider(); + this.testloggerManager = new DummyTestLoggerManager(); + this.executor = new EnableBlameArgumentExecutor(this.settingsProvider,this.testloggerManager); + CollectArgumentExecutor.EnabledDataCollectors.Clear(); + } + + [TestMethod] + public void GetMetadataShouldReturnEnableBlameArgumentProcessorCapabilities() + { + var processor = new EnableBlameArgumentProcessor(); + Assert.IsTrue(processor.Metadata.Value is EnableBlameArgumentProcessorCapabilities); + } + + [TestMethod] + public void GetExecuterShouldReturnEnableBlameArgumentProcessorCapabilities() + { + var processor = new EnableBlameArgumentProcessor(); + Assert.IsTrue(processor.Executor.Value is EnableBlameArgumentExecutor); + } + + [TestMethod] + public void CapabilitiesShouldReturnAppropriateProperties() + { + var capabilities = new EnableBlameArgumentProcessorCapabilities(); + + Assert.AreEqual("/Blame", capabilities.CommandName); + Assert.AreEqual(false, capabilities.IsAction); + Assert.AreEqual(ArgumentProcessorPriority.Blame, capabilities.Priority); + + Assert.AreEqual(false, capabilities.AllowMultiple); + Assert.AreEqual(false, capabilities.AlwaysExecute); + Assert.AreEqual(false, capabilities.IsSpecialCommand); + } + + [TestMethod] + public void InitializeShouldCreateEntryForBlameInRunSettingsIfNotAlreadyPresent() + { + var runsettingsString = string.Format(DefaultRunSettings, ""); + var runsettings = new RunSettings(); + runsettings.LoadSettingsXml(runsettingsString); + this.settingsProvider.SetActiveRunSettings(runsettings); + + this.executor.Initialize(""); + + Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); + Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + } + } +} From af00f67545e4aa08f325740f5b2a3e872c06cbf1 Mon Sep 17 00:00:00 2001 From: t-vanidh Date: Thu, 6 Jul 2017 11:38:03 +0530 Subject: [PATCH 2/9] Unit tests added and minor changes --- .../BlameCollector.cs | 35 ++++- .../BlameLogger.cs | 33 ++--- .../Constants.cs | 17 +-- .../Friends.cs | 14 ++ .../Interfaces/IBlameReaderWriter.cs | 2 +- ...oft.TestPlatform.BlameDataCollector.csproj | 9 ++ .../Resources/Resources.Designer.cs | 73 +++++++++++ .../Resources/Resources.resx | 123 ++++++++++++++++++ .../Resources/xlf/Resources.cs.xlf | 34 +++++ .../Resources/xlf/Resources.de.xlf | 34 +++++ .../Resources/xlf/Resources.es.xlf | 34 +++++ .../Resources/xlf/Resources.fr.xlf | 34 +++++ .../Resources/xlf/Resources.it.xlf | 34 +++++ .../Resources/xlf/Resources.ja.xlf | 34 +++++ .../Resources/xlf/Resources.ko.xlf | 34 +++++ .../Resources/xlf/Resources.pl.xlf | 34 +++++ .../Resources/xlf/Resources.pt-BR.xlf | 34 +++++ .../Resources/xlf/Resources.ru.xlf | 34 +++++ .../Resources/xlf/Resources.tr.xlf | 34 +++++ .../Resources/xlf/Resources.xlf | 11 ++ .../Resources/xlf/Resources.zh-Hans.xlf | 34 +++++ .../Resources/xlf/Resources.zh-Hant.xlf | 34 +++++ .../XmlReaderWriter.cs | 39 ++++-- src/vstest.console/Internal/ConsoleLogger.cs | 21 +-- .../EnableBlameArgumentProcessor.cs | 5 +- .../Utilities/ArgumentProcessorPriority.cs | 5 - .../Utilities/HelpContentPriority.cs | 5 - src/vstest.console/Resources/Resources.resx | 4 +- .../Resources/xlf/Resources.cs.xlf | 7 + .../Resources/xlf/Resources.de.xlf | 7 + .../Resources/xlf/Resources.es.xlf | 7 + .../Resources/xlf/Resources.fr.xlf | 7 + .../Resources/xlf/Resources.it.xlf | 7 + .../Resources/xlf/Resources.ja.xlf | 7 + .../Resources/xlf/Resources.ko.xlf | 7 + .../Resources/xlf/Resources.pl.xlf | 7 + .../Resources/xlf/Resources.pt-BR.xlf | 7 + .../Resources/xlf/Resources.ru.xlf | 7 + .../Resources/xlf/Resources.tr.xlf | 7 + .../Resources/xlf/Resources.xlf | 7 + .../Resources/xlf/Resources.zh-Hans.xlf | 7 + .../Resources/xlf/Resources.zh-Hant.xlf | 7 + .../BlameCollectorTests.cs | 62 ++++++++- .../BlameLoggerTests.cs | 20 ++- .../XmlReaderWriterTests.cs | 55 ++++++-- .../CollectArgumentProcessorTests.cs | 2 +- .../EnableBlameArgumentProcessorTests.cs | 15 ++- 47 files changed, 984 insertions(+), 106 deletions(-) create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Friends.cs create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.Designer.cs create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.resx create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.cs.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.de.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.es.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.fr.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.it.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ja.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ko.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pl.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ru.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.tr.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf create mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs b/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs index 6f5186a5fd..4d7f92b5e3 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs +++ b/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs @@ -79,7 +79,7 @@ public override void Initialize(XmlElement configurationElement, /// private void Events_TestCaseStart(object sender, TestCaseStartEventArgs e) { - EqtTrace.Info("Blame Collector : " + Constants.TestCaseStart); + EqtTrace.Info("Blame Collector : Test Case Start"); TestCase testcase = new TestCase(e.TestElement.FullyQualifiedName, e.TestElement.ExecutorUri, e.TestElement.Source); this.testSequence.Add(testcase); this.testStartCount++; @@ -90,7 +90,7 @@ private void Events_TestCaseStart(object sender, TestCaseStartEventArgs e) /// private void Events_TestCaseEnd(object sender, TestCaseEndEventArgs e) { - EqtTrace.Info("Blame Collector : " + Constants.TestCaseEnd); + EqtTrace.Info("Blame Collector : Test Case End"); this.testEndCount++; } @@ -99,11 +99,14 @@ private void Events_TestCaseEnd(object sender, TestCaseEndEventArgs e) /// private void SessionEnded_Handler(object sender, SessionEndEventArgs args) { - EqtTrace.Info("Blame Collector :" + Constants.TestSessionEnd); - if (this.testStartCount != this.testEndCount) + EqtTrace.Info("Blame Collector : Session End"); + + // If the last test crashes, it will not invoke a test case end and therefore + // In case of crash testStartCount will be greater than testEndCount and we need to send write the sequence + if (this.testStartCount > this.testEndCount) { var filepath = Path.Combine(AppContext.BaseDirectory, Constants.AttachmentFileName); - this.blameReaderWriter.WriteTestSequence(this.testSequence, filepath); + filepath = this.blameReaderWriter.WriteTestSequence(this.testSequence, filepath); this.dataCollectionSink.SendFileAsync(this.context.SessionDataCollectionContext, filepath, true); } DeregisterEvents(); @@ -118,5 +121,27 @@ private void DeregisterEvents() this.events.TestCaseStart -= this.Events_TestCaseStart; this.events.TestCaseEnd -= this.Events_TestCaseEnd; } + + /// + /// Getter method + /// + internal int TestStartCount + { + get + { + return this.testStartCount; + } + } + + /// + /// Getter method + /// + internal int TestEndCount + { + get + { + return this.testEndCount; + } + } } } diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs b/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs index 1baa8516d4..fcfbae5554 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs +++ b/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs @@ -8,7 +8,7 @@ namespace Microsoft.TestPlatform.BlameDataCollector using Microsoft.VisualStudio.TestPlatform.Utilities; using System; using System.Collections.Generic; - using System.Globalization; + using Microsoft.TestPlatform.BlameDataCollector.Resources; [FriendlyName(BlameLogger.FriendlyName)] [ExtensionUri(BlameLogger.ExtensionUri)] @@ -89,7 +89,7 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) // Gets the faulty test case if test aborted var testCaseName = GetFaultyTestCase(e); - string reason = Constants.TestRunAbortReason + testCaseName; + string reason = Resources.Resources.AbortedTestRun + testCaseName; Output.Error(reason); } @@ -102,33 +102,20 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) /// private string GetFaultyTestCase(TestRunCompleteEventArgs e) { - string testname = null; foreach (var attachmentSet in e.AttachmentSets) { if (attachmentSet.DisplayName.Equals(Constants.BlameDataCollectorName)) { - testname = GetLastTestFromFile(attachmentSet.Attachments[0].Uri.LocalPath); - break; + var filepath = attachmentSet.Attachments[0].Uri.LocalPath; + List testCaseList = this.blameReaderWriter.ReadTestSequence(filepath); + if (testCaseList.Count > 0) + { + var testcase = testCaseList[testCaseList.Count - 1]; + return testcase.FullyQualifiedName; + } + return String.Empty; } } - return testname; - } - - /// - /// Reads file for last test case - /// - public string GetLastTestFromFile(string filepath) - { - try - { - List testCaseList = this.blameReaderWriter.ReadTestSequence(filepath); - var testcase = testCaseList[testCaseList.Count - 1]; - return testcase.FullyQualifiedName; - } - catch (NullReferenceException e) - { - EqtTrace.Error("Blame Logger: GetLastTestFromFile : " + e); - } return String.Empty; } diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs b/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs index 4380d6e023..83c7c24920 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs @@ -8,21 +8,6 @@ namespace Microsoft.TestPlatform.BlameDataCollector /// internal static class Constants { - /// - /// The test session end constant. - /// - public const string TestSessionEnd = "TestSessionEnd"; - - /// - /// The test case start constant. - /// - public const string TestCaseStart = "TestCaseStart"; - - /// - /// The test case end constant. - /// - public const string TestCaseEnd = "TestCaseEnd"; - /// /// Root node name for Xml file. /// @@ -36,7 +21,7 @@ internal static class Constants /// /// Attachment File name. /// - public const string AttachmentFileName = "TestSequence.xml"; + public const string AttachmentFileName = "Sequence"; /// /// Test Name Attribute. diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Friends.cs b/src/Microsoft.TestPlatform.BlameDataCollector/Friends.cs new file mode 100644 index 0000000000..18ce328da5 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Friends.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Runtime.CompilerServices; + +#region Product Assemblies + +#endregion + +#region Test Assemblies + +[assembly: InternalsVisibleTo("Microsoft.TestPlatform.BlameDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] + +#endregion diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs b/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs index 8e094fb7aa..73d342f011 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs @@ -13,7 +13,7 @@ public interface IBlameReaderWriter /// /// List of tests in sequence /// The path of file - void WriteTestSequence(List testSequence, string filePath); + string WriteTestSequence(List testSequence, string filePath); /// /// Reads all tests from file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj b/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj index 1119fef0a7..3ca456c705 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj @@ -16,6 +16,9 @@ + + + @@ -45,5 +48,11 @@ + + + ResXFileCodeGenerator + Resources.Designer.cs + + diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.Designer.cs new file mode 100644 index 0000000000..d4c0f0df92 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.TestPlatform.BlameDataCollector.Resources { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.TestPlatform.BlameDataCollector.Resources.Resources", typeof(Resources).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The active Test Run was aborted because the host process exited unexpectedly while executing test . + /// + internal static string AbortedTestRun { + get { + return ResourceManager.GetString("AbortedTestRun", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.resx b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.resx new file mode 100644 index 0000000000..200337636f --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The active Test Run was aborted because the host process exited unexpectedly while executing test + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.cs.xlf new file mode 100644 index 0000000000..96a4b8fd93 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.cs.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + Aktivní testovací běh se přerušil. Důvod: {0} + + + Aktivní Test spuštění bylo přerušeno. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.de.xlf new file mode 100644 index 0000000000..1f22190166 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.de.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + Der aktive Testlauf wurde abgebrochen. Grund: {0} + + + Aktive Testlauf wurde abgebrochen. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.es.xlf new file mode 100644 index 0000000000..6dd8b25e2d --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.es.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + Se ha anulado la serie de pruebas activa. Motivo: {0} + + + Se anuló la ejecución de prueba activa. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.fr.xlf new file mode 100644 index 0000000000..09a6b51eed --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.fr.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + La série de tests active a été abandonnée. Raison : {0} + + + La série de tests active a été abandonnée. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.it.xlf new file mode 100644 index 0000000000..624c75b5a0 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.it.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + L'esecuzione dei test attivi è stata interrotta. Motivo: {0} + + + Esecuzione dei Test attiva è stata interrotta. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ja.xlf new file mode 100644 index 0000000000..47a2308a0b --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ja.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + アクティブなテストの実行が中止されました。理由: {0} + + + アクティブなテストの実行は中止されました。 + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ko.xlf new file mode 100644 index 0000000000..5f2220c67b --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ko.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + 활성 테스트 실행이 중단되었습니다. 이유: {0} + + + 활성 테스트 실행이 중단 되었습니다. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pl.xlf new file mode 100644 index 0000000000..39533971a4 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pl.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + Aktywne uruchomienie testu zostało przerwane. Przyczyna: {0} + + + Aktywne Uruchom Test została przerwana. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf new file mode 100644 index 0000000000..a7c7ba5a8e --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + A execução de teste ativa foi anulada. Motivo: {0} + + + Execução de teste ativa foi anulada. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ru.xlf new file mode 100644 index 0000000000..2e5eaed6d9 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ru.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + Активный тестовый запуск прерван. Причина: {0} + + + Прервано активного тестового запуска. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.tr.xlf new file mode 100644 index 0000000000..5ab22f5b6c --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.tr.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + Etkin test çalıştırması iptal edildi. Nedeni: {0} + + + Etkin Test çalışmasını iptal edildi. + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.xlf new file mode 100644 index 0000000000..ce938ceda9 --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.xlf @@ -0,0 +1,11 @@ + + + + + + The active Test Run was aborted because the host process exited unexpectedly while executing test + + + + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf new file mode 100644 index 0000000000..bb83a6cdbd --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + 活动的测试运行已中止。原因: {0} + + + 活动测试运行已中止。 + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf new file mode 100644 index 0000000000..54d3c2538e --- /dev/null +++ b/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf @@ -0,0 +1,34 @@ + + + +
+ + 29 + 24.65 + 24.65 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 29 + 0 + +
+ + + The active Test Run was aborted because the host process exited unexpectedly while executing test + 使用中的測試回合已中止。原因: {0} + + + 活动测试运行已中止。 + + fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1" + + +
+
\ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs b/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs index a5d6969021..69fc595278 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs +++ b/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs @@ -33,11 +33,14 @@ public XmlReaderWriter(IFileHelper fileHelper) /// /// Adds tests to document and saves document to file /// - public void WriteTestSequence(List testSequence, string filePath) + public string WriteTestSequence(List testSequence, string filePath) { ValidateArg.NotNull(testSequence, nameof(testSequence)); ValidateArg.NotNullOrEmpty(filePath, nameof(filePath)); + filePath = filePath + ".xml"; + + // Writing test sequence var xmlDocument = new XmlDocument(); var xmlDeclaration = xmlDocument.CreateNode(XmlNodeType.XmlDeclaration, string.Empty, string.Empty); var blameTestRoot = xmlDocument.CreateElement(Constants.BlameRootNode); @@ -48,24 +51,25 @@ public void WriteTestSequence(List testSequence, string filePath) var testElement = xmlDocument.CreateElement(Constants.BlameTestNode); testElement.SetAttribute(Constants.TestNameAttribute, testCase.FullyQualifiedName); testElement.SetAttribute(Constants.TestSourceAttribute, testCase.Source); + blameTestRoot.AppendChild(testElement); } xmlDocument.AppendChild(blameTestRoot); - using (var stream = this.fileHelper.GetStream(filePath, FileMode.Create)) { xmlDocument.Save(stream); } + return filePath; } /// /// Reads All test case from file /// - /// The path of saved file + /// The path of test sequence file /// Test Case List public List ReadTestSequence(string filePath) { - ValidateArg.NotNullOrEmpty(filePath, nameof(filePath)); + ValidateArg.NotNull(filePath, nameof(filePath)); if (!fileHelper.Exists(filePath)) { @@ -73,19 +77,26 @@ public List ReadTestSequence(string filePath) } List testCaseList = new List(); - var xmlDocument = new XmlDocument(); - using (var stream = this.fileHelper.GetStream(filePath, FileMode.Open)) + try { - xmlDocument.Load(stream); + // Reading test sequence + var xmlDocument = new XmlDocument(); + using (var stream = this.fileHelper.GetStream(filePath, FileMode.Open)) + { + xmlDocument.Load(stream); + } + var root = xmlDocument.LastChild; + foreach (XmlNode node in root) + { + TestCase testCase = new TestCase(); + testCase.FullyQualifiedName = node.Attributes[Constants.TestNameAttribute].Value; + testCase.Source = node.Attributes[Constants.TestSourceAttribute].Value; + testCaseList.Add(testCase); + } } - var root = xmlDocument.LastChild; - - foreach (XmlNode node in root) + catch (XmlException xmlException) { - TestCase testCase = new TestCase(); - testCase.FullyQualifiedName = node.Attributes[Constants.TestNameAttribute].Value; - testCase.Source = node.Attributes[Constants.TestSourceAttribute].Value; - testCaseList.Add(testCase); + EqtTrace.Warning("XmlReaderWriter : Exception ", xmlException); } return testCaseList; } diff --git a/src/vstest.console/Internal/ConsoleLogger.cs b/src/vstest.console/Internal/ConsoleLogger.cs index ad9d5e13b1..9431446920 100644 --- a/src/vstest.console/Internal/ConsoleLogger.cs +++ b/src/vstest.console/Internal/ConsoleLogger.cs @@ -17,7 +17,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Internal using Microsoft.VisualStudio.TestPlatform.Utilities; using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; - + /// /// Logger for sending output to the console. /// All the console logger messages prints to Standard Output with respective color, except OutputLevel.Error messages @@ -397,26 +397,17 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) // Printing Run-level Attachments if (runLevelAttachementCount > 0) { - foreach (var attachmentSet in e.AttachmentSets) - { - if (!attachmentSet.DisplayName.Equals(BlameDataCollectorName)) - { - Output.Information(CommandLineResources.AttachmentsBanner); - break; - } - } + Output.Information(CommandLineResources.AttachmentsBanner); } + if (runLevelAttachementCount > 0) { foreach (var attachmentSet in e.AttachmentSets) { - if (!attachmentSet.DisplayName.Equals(BlameDataCollectorName)) + foreach (var uriDataAttachment in attachmentSet.Attachments) { - foreach (var uriDataAttachment in attachmentSet.Attachments) - { - var attachmentOutput = string.Format(CultureInfo.CurrentCulture, CommandLineResources.AttachmentOutputFormat, uriDataAttachment.Uri.LocalPath); - Output.Information(attachmentOutput); - } + var attachmentOutput = string.Format(CultureInfo.CurrentCulture, CommandLineResources.AttachmentOutputFormat, uriDataAttachment.Uri.LocalPath); + Output.Information(attachmentOutput); } } Output.WriteLine(String.Empty, OutputLevel.Information); diff --git a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs index 87b219e5c4..d9aa11bb10 100644 --- a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs +++ b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs @@ -8,7 +8,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; using Microsoft.VisualStudio.TestPlatform.Common.Interfaces; using Microsoft.VisualStudio.TestPlatform.Common.Logging; - using System.Collections.Generic; using System.Diagnostics.Contracts; using Microsoft.VisualStudio.TestPlatform.Common; using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities; @@ -77,11 +76,11 @@ internal class EnableBlameArgumentProcessorCapabilities : BaseArgumentProcessorC public override bool IsAction => false; - public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.Blame; + public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.Diag; public override string HelpContentResourceName => CommandLineResources.EnableBlameUsage; - public override HelpContentPriority HelpPriority => HelpContentPriority.EnableBlameArgumentProcessorHelpPriority; + public override HelpContentPriority HelpPriority => HelpContentPriority.EnableDiagArgumentProcessorHelpPriority; } /// diff --git a/src/vstest.console/Processors/Utilities/ArgumentProcessorPriority.cs b/src/vstest.console/Processors/Utilities/ArgumentProcessorPriority.cs index 6893c50b12..b54592761e 100644 --- a/src/vstest.console/Processors/Utilities/ArgumentProcessorPriority.cs +++ b/src/vstest.console/Processors/Utilities/ArgumentProcessorPriority.cs @@ -23,11 +23,6 @@ internal enum ArgumentProcessorPriority /// Diag = 1, - /// - /// Priority of the Blame processor. - /// - Blame = 1, - /// /// Priority of processors related to design mode. This needs to be higher priority /// since some of the functionalities (like logger) depend on this. diff --git a/src/vstest.console/Processors/Utilities/HelpContentPriority.cs b/src/vstest.console/Processors/Utilities/HelpContentPriority.cs index b8ba2b078e..53c716518e 100644 --- a/src/vstest.console/Processors/Utilities/HelpContentPriority.cs +++ b/src/vstest.console/Processors/Utilities/HelpContentPriority.cs @@ -97,11 +97,6 @@ internal enum HelpContentPriority /// EnableDiagArgumentProcessorHelpPriority, - /// - /// EnableBlameArgumentProcessor Help - /// - EnableBlameArgumentProcessorHelpPriority, - /// /// EnableLoggerArgumentProcessor Help /// diff --git a/src/vstest.console/Resources/Resources.resx b/src/vstest.console/Resources/Resources.resx index 58c77b4b0d..db918ce79a 100644 --- a/src/vstest.console/Resources/Resources.resx +++ b/src/vstest.console/Resources/Resources.resx @@ -657,6 +657,6 @@ --Blame|/Blame - Enable Blame mode to get name of the faulty test case in event of a test host crash. + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. - + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.cs.xlf b/src/vstest.console/Resources/xlf/Resources.cs.xlf index c9a9729357..ace01a35b5 100644 --- a/src/vstest.console/Resources/xlf/Resources.cs.xlf +++ b/src/vstest.console/Resources/xlf/Resources.cs.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.de.xlf b/src/vstest.console/Resources/xlf/Resources.de.xlf index 9277fbaaa3..1efece4495 100644 --- a/src/vstest.console/Resources/xlf/Resources.de.xlf +++ b/src/vstest.console/Resources/xlf/Resources.de.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.es.xlf b/src/vstest.console/Resources/xlf/Resources.es.xlf index 11b08e625e..f42e3748fc 100644 --- a/src/vstest.console/Resources/xlf/Resources.es.xlf +++ b/src/vstest.console/Resources/xlf/Resources.es.xlf @@ -1560,6 +1560,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.fr.xlf b/src/vstest.console/Resources/xlf/Resources.fr.xlf index 2f703cf235..d022102c1f 100644 --- a/src/vstest.console/Resources/xlf/Resources.fr.xlf +++ b/src/vstest.console/Resources/xlf/Resources.fr.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.it.xlf b/src/vstest.console/Resources/xlf/Resources.it.xlf index 54b9668bd2..4594be8567 100644 --- a/src/vstest.console/Resources/xlf/Resources.it.xlf +++ b/src/vstest.console/Resources/xlf/Resources.it.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ja.xlf b/src/vstest.console/Resources/xlf/Resources.ja.xlf index 949820bc40..47fc9ce4bc 100644 --- a/src/vstest.console/Resources/xlf/Resources.ja.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ja.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ko.xlf b/src/vstest.console/Resources/xlf/Resources.ko.xlf index 410322433d..9c30d80713 100644 --- a/src/vstest.console/Resources/xlf/Resources.ko.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ko.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.pl.xlf b/src/vstest.console/Resources/xlf/Resources.pl.xlf index 6e45f9a9bb..33ad4fd832 100644 --- a/src/vstest.console/Resources/xlf/Resources.pl.xlf +++ b/src/vstest.console/Resources/xlf/Resources.pl.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf b/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf index ca72ccb7a2..5ed15b2362 100644 --- a/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf +++ b/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf @@ -1551,6 +1551,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ru.xlf b/src/vstest.console/Resources/xlf/Resources.ru.xlf index 849c66f7c7..af328b9b13 100644 --- a/src/vstest.console/Resources/xlf/Resources.ru.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ru.xlf @@ -1553,6 +1553,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.tr.xlf b/src/vstest.console/Resources/xlf/Resources.tr.xlf index bd3a5d31e1..2409954c02 100644 --- a/src/vstest.console/Resources/xlf/Resources.tr.xlf +++ b/src/vstest.console/Resources/xlf/Resources.tr.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.xlf b/src/vstest.console/Resources/xlf/Resources.xlf index 349a8149e1..e25992a419 100644 --- a/src/vstest.console/Resources/xlf/Resources.xlf +++ b/src/vstest.console/Resources/xlf/Resources.xlf @@ -700,6 +700,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf b/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf index 8c8e3f031d..da83f70779 100644 --- a/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf @@ -1551,6 +1551,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf b/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf index c9627a2f22..c36f4cefe1 100644 --- a/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf @@ -1552,6 +1552,13 @@ Debug Traces Messages: + + --Blame|/Blame + Runs the test in blame mode. This option is helpful in isolating the problematic test causing test host crash. It creates an output file in the current directory as "Sequence.xml", that captures the order of execution of test before the crash. + --Blame|/Blame + Enable Blame mode to get name of the faulty test case in event of a test host crash. + + \ No newline at end of file diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs index 5457379e5e..a97343234c 100644 --- a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs +++ b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs @@ -54,20 +54,76 @@ public void InitializeShouldThrowExceptionIfDataCollectionLoggerIsNull() } [TestMethod] - public void TriggerSessionEndedHandlerShouldWriteToFile() + public void TriggerTestCaseStartedHandlerShouldIncreaseTestStartCount() + { + TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); + + // Initializing Blame Data Collector + this.blameDataCollector.Initialize(this.configurationElement, + this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, + this.mockLogger.Object, this.context); + + // Setup and Raise Session End Event + this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase)); + + // Assert + Assert.AreEqual(1, this.blameDataCollector.TestStartCount); + } + + [TestMethod] + public void TriggerTestCaseEndedHandlerShouldIncreaseTestEndCount() + { + TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); + + // Initializing Blame Data Collector + this.blameDataCollector.Initialize(this.configurationElement, + this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, + this.mockLogger.Object, this.context); + + // Setup and Raise Session End Event + this.mockDataColectionEvents.Raise(x => x.TestCaseEnd += null, new TestCaseEndEventArgs(testcase, TestOutcome.Passed)); + + // Assert + Assert.AreEqual(1, this.blameDataCollector.TestEndCount); + } + + [TestMethod] + public void TriggerSessionEndedHandlerShouldWriteToFileIfTestStartCountIsGreater() { // Initializing Blame Data Collector this.blameDataCollector.Initialize(this.configurationElement, this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, this.mockLogger.Object, this.context); - var filepath = Path.Combine(AppContext.BaseDirectory, "TestSequence.xml"); + var filepath = Path.Combine(AppContext.BaseDirectory, "Sequence"); + TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); - // Setup and Raise Session End Event + // Setup and Raise TestCaseStart and Session End Event this.mockDataCollectionSink.Setup(x => x.SendFileAsync(It.IsAny(), It.IsAny(), It.IsAny())); + this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase)); this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(dataCollectionContext)); // Verify WriteTestSequence Call this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), filepath), Times.Once); } + + [TestMethod] + public void TriggerSessionEndedHandlerShouldNotWriteToTestStartCountIsSameAsTestEndCountFile() + { + // Initializing Blame Data Collector + this.blameDataCollector.Initialize(this.configurationElement, + this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, + this.mockLogger.Object, this.context); + var filepath = Path.Combine(AppContext.BaseDirectory, "TestSequence.xml"); + TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); + + // Setup and Raise TestCaseStart and Session End Event + this.mockDataCollectionSink.Setup(x => x.SendFileAsync(It.IsAny(), It.IsAny(), It.IsAny())); + this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase)); + this.mockDataColectionEvents.Raise(x => x.TestCaseEnd += null, new TestCaseEndEventArgs(testcase, TestOutcome.Passed)); + this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(dataCollectionContext)); + + // Verify WriteTestSequence Call + this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), filepath), Times.Never); + } } } diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs index 57369f3f79..9cf4ca41c7 100644 --- a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs +++ b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs @@ -53,7 +53,7 @@ public void InitializeShouldThrowExceptionIfEventsIsNull() } [TestMethod] - public void TestResulCompleteHandlerShouldThowExceptionIfEventArgsIsNull() + public void TestResultCompleteHandlerShouldThrowExceptionIfEventArgsIsNull() { // Raise an event on mock object Assert.ThrowsException(() => @@ -63,7 +63,7 @@ public void TestResulCompleteHandlerShouldThowExceptionIfEventArgsIsNull() } [TestMethod] - public void TestRunCompleteHandlerShouldGetFaultyTestCaseIfTestRunAborted() + public void TestRunCompleteHandlerShouldGetFaultyTestRunIfTestRunAborted() { // Initialize var attachmentSet = new AttachmentSet(new Uri("test://uri"), "Blame"); @@ -89,6 +89,22 @@ public void TestRunCompleteHandlerShouldGetFaultyTestCaseIfTestRunAborted() this.mockBlameReaderWriter.Verify(x => x.ReadTestSequence(It.IsAny()), Times.Once); } + [TestMethod] + public void TestRunCompleteHandlerShouldNotReadFileIfTestRunNotAborted() + { + // Initialize Blame Logger + this.blameLogger.Initialize(this.events.Object, null); + + // Setup and Raise event + this.mockBlameReaderWriter.Setup(x => x.ReadTestSequence(It.IsAny())); + this.testRunRequest.Raise( + m => m.OnRunCompletion += null, + new TestRunCompleteEventArgs(stats: null, isCanceled: false, isAborted: false, error: null, attachmentSets: null, elapsedTime: new TimeSpan(1, 0, 0, 0))); + + // Verify Call + this.mockBlameReaderWriter.Verify(x => x.ReadTestSequence(It.IsAny()), Times.Never); + } + internal class DummyTestLoggerManager : TestLoggerManager { public DummyTestLoggerManager() : base(TestSessionMessageLogger.Instance, new InternalTestLoggerEvents(TestSessionMessageLogger.Instance)) diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs index 2f60ebf4be..0296977b23 100644 --- a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs +++ b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System.IO; + namespace Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests { using System; @@ -16,13 +18,17 @@ public class XmlReaderWriterTests { private XmlReaderWriter xmlReaderWriter; private Mock mockFileHelper; + private Mock mockStream; + public XmlReaderWriterTests() { this.mockFileHelper = new Mock(); this.xmlReaderWriter = new XmlReaderWriter(this.mockFileHelper.Object); - } - + this.mockStream = new Mock(); + + } + [TestMethod] public void WriteTestSequenceShouldThrowExceptionIfFilePathIsNull() { @@ -69,23 +75,52 @@ public void ReadTestSequenceShouldThrowExceptionIfFilePathIsNull() } [TestMethod] - public void ReadTestSequenceShouldThrowExceptionIfFilePathIsEmpty() + public void ReadTestSequenceShouldThrowExceptionIfFileNotFound() { - Assert.ThrowsException(() => + this.mockFileHelper.Setup(m => m.Exists(It.IsAny())).Returns(false); + + Assert.ThrowsException(() => { this.xmlReaderWriter.ReadTestSequence(String.Empty); }); } [TestMethod] - public void ReadTestSequenceShouldThrowExceptionIfFileNotFound() + public void ReadTestSequenceShouldReadFileStream() { - this.mockFileHelper.Setup(m => m.Exists(It.IsAny())).Returns(false); + // Setup + this.mockFileHelper.Setup(m => m.Exists(It.IsAny())).Returns(true); + this.mockFileHelper.Setup(m => m.GetStream("path.xml", FileMode.Open, FileAccess.ReadWrite)).Returns(this.mockStream.Object); - Assert.ThrowsException(() => - { - this.xmlReaderWriter.ReadTestSequence(String.Empty); - }); + // Call to Read Test Sequence + this.xmlReaderWriter.ReadTestSequence("path.xml"); + + // Verify Call to fileHelper + this.mockFileHelper.Verify(x => x.GetStream("path.xml", FileMode.Open, FileAccess.ReadWrite)); + + // Verify Call to stream read + this.mockStream.Verify(x => x.Read(It.IsAny(), It.IsAny(), It.IsAny())); + + } + + [TestMethod] + public void WriteTestSequenceShouldWriteFileStream() + { + List testCaseList = new List(); + + // Setup + this.mockFileHelper.Setup(m => m.Exists(It.IsAny())).Returns(true); + this.mockFileHelper.Setup(m => m.GetStream("path.xml", FileMode.Create, FileAccess.ReadWrite)).Returns(this.mockStream.Object); + this.mockStream.Setup(x => x.CanWrite).Returns(true); + this.mockStream.Setup(x => x.Write(It.IsAny(), It.IsAny(), It.IsAny())); + + this.xmlReaderWriter.WriteTestSequence(testCaseList, "path"); + + // Verify Call to fileHelper + this.mockFileHelper.Verify(x => x.GetStream("path.xml", FileMode.Create, FileAccess.ReadWrite)); + + // Verify Call to stream write + this.mockStream.Verify(x => x.Write(It.IsAny(), It.IsAny(), It.IsAny())); } } } diff --git a/test/vstest.console.UnitTests/Processors/CollectArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/CollectArgumentProcessorTests.cs index 72217d0ee0..696c7b260f 100644 --- a/test/vstest.console.UnitTests/Processors/CollectArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/CollectArgumentProcessorTests.cs @@ -132,7 +132,7 @@ public void InitializeShouldEnableMultipleCollectorsWhenCalledMoreThanOnce() Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); } - + #endregion } } diff --git a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs index 7e204f8f5c..fee6dae7e5 100644 --- a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs @@ -1,12 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; + namespace vstest.console.UnitTests.Processors { using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors; using Microsoft.VisualStudio.TestPlatform.Common; using Microsoft.VisualStudio.TestTools.UnitTesting; using vstest.console.UnitTests.TestDoubles; + using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; [TestClass] public class EnableBlameArgumentProcessorTests @@ -45,7 +48,9 @@ public void CapabilitiesShouldReturnAppropriateProperties() Assert.AreEqual("/Blame", capabilities.CommandName); Assert.AreEqual(false, capabilities.IsAction); - Assert.AreEqual(ArgumentProcessorPriority.Blame, capabilities.Priority); + Assert.AreEqual(ArgumentProcessorPriority.Diag, capabilities.Priority); + Assert.AreEqual(HelpContentPriority.EnableDiagArgumentProcessorHelpPriority, capabilities.HelpPriority); + Assert.AreEqual(CommandLineResources.EnableBlameUsage, capabilities.HelpContentResourceName); Assert.AreEqual(false, capabilities.AllowMultiple); Assert.AreEqual(false, capabilities.AlwaysExecute); @@ -65,5 +70,13 @@ public void InitializeShouldCreateEntryForBlameInRunSettingsIfNotAlreadyPresent( Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); } + + [TestMethod] + public void ExecutorInitializeShouldAddBlameLoggerInLoggerList() + { + executor.Initialize(String.Empty); + + Assert.IsTrue(testloggerManager.LoggerExist("blame")); + } } } From 46f87dd26cb83b665ee63732fe1135ae75909bed Mon Sep 17 00:00:00 2001 From: t-vanidh Date: Sat, 8 Jul 2017 18:43:01 +0530 Subject: [PATCH 3/9] Suggested changes made --- TestPlatform.sln | 30 ++-- scripts/build.ps1 | 2 +- .../Friends.cs | 14 -- src/Microsoft.TestPlatform.Common/Friends.cs | 2 +- .../BlameCollector.cs | 94 ++++++------ .../BlameLogger.cs | 83 +++++++---- .../Constants.cs | 7 +- .../Interfaces/IBlameReaderWriter.cs | 2 +- ...form.Extensions.BlameDataCollector.csproj} | 29 ++-- .../Resources/Resources.Designer.cs | 11 +- .../Resources/Resources.resx | 0 .../Resources/xlf/Resources.cs.xlf | 16 +- .../Resources/xlf/Resources.de.xlf | 16 +- .../Resources/xlf/Resources.es.xlf | 16 +- .../Resources/xlf/Resources.fr.xlf | 16 +- .../Resources/xlf/Resources.it.xlf | 16 +- .../Resources/xlf/Resources.ja.xlf | 16 +- .../Resources/xlf/Resources.ko.xlf | 16 +- .../Resources/xlf/Resources.pl.xlf | 16 +- .../Resources/xlf/Resources.pt-BR.xlf | 16 +- .../Resources/xlf/Resources.ru.xlf | 16 +- .../Resources/xlf/Resources.tr.xlf | 16 +- .../Resources/xlf/Resources.xlf | 1 + .../Resources/xlf/Resources.zh-Hans.xlf | 16 +- .../Resources/xlf/Resources.zh-Hant.xlf | 16 +- .../XmlReaderWriter.cs | 52 +++++-- .../FileTransferInformation.cs | 2 +- src/package/sign/sign.proj | 1 + src/vstest.console/Internal/ConsoleLogger.cs | 2 - .../Processors/CollectArgumentProcessor.cs | 57 +++---- .../EnableBlameArgumentProcessor.cs | 33 +--- .../EnableCodeCoverageArgumentProcessor.cs | 23 +-- ...atform.BlameDataCollector.UnitTests.csproj | 56 ------- .../BlameCollectorTests.cs | 141 ++++++++++-------- .../BlameLoggerTests.cs | 105 ++++++++++--- ...nsions.BlameDataCollector.UnitTests.csproj | 39 +++++ .../XmlReaderWriterTests.cs | 93 ++++++++---- .../EnableBlameArgumentProcessorTests.cs | 5 +- ...nableCodeCoverageArgumentProcessorTests.cs | 1 + 39 files changed, 565 insertions(+), 528 deletions(-) delete mode 100644 src/Microsoft.TestPlatform.BlameDataCollector/Friends.cs rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/BlameCollector.cs (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/BlameLogger.cs (60%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Constants.cs (81%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Interfaces/IBlameReaderWriter.cs (93%) rename src/{Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj => Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj} (55%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/Resources.Designer.cs (93%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/Resources.resx (100%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.cs.xlf (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.de.xlf (64%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.es.xlf (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.fr.xlf (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.it.xlf (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.ja.xlf (62%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.ko.xlf (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.pl.xlf (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.pt-BR.xlf (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.ru.xlf (61%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.tr.xlf (63%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.xlf (80%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.zh-Hans.xlf (64%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/Resources/xlf/Resources.zh-Hant.xlf (64%) rename src/{Microsoft.TestPlatform.BlameDataCollector => Microsoft.TestPlatform.Extensions.BlameDataCollector}/XmlReaderWriter.cs (72%) delete mode 100644 test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj rename test/{Microsoft.TestPlatform.BlameDataCollector.UnitTests => Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests}/BlameCollectorTests.cs (52%) rename test/{Microsoft.TestPlatform.BlameDataCollector.UnitTests => Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests}/BlameLoggerTests.cs (53%) create mode 100644 test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj rename test/{Microsoft.TestPlatform.BlameDataCollector.UnitTests => Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests}/XmlReaderWriterTests.cs (60%) diff --git a/TestPlatform.sln b/TestPlatform.sln index 8b0d572886..363ab8f621 100644 --- a/TestPlatform.sln +++ b/TestPlatform.sln @@ -151,9 +151,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.TestHostProvider", "src\Microsoft.TestPlatform.TestHostProvider\Microsoft.TestPlatform.TestHostProvider.csproj", "{11ECCB8B-6958-42A7-BD58-88C09CB149B2}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.BlameDataCollector", "src\Microsoft.TestPlatform.BlameDataCollector\Microsoft.TestPlatform.BlameDataCollector.csproj", "{76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Extensions.BlameDataCollector", "src\Microsoft.TestPlatform.Extensions.BlameDataCollector\Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj", "{76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.BlameDataCollector.UnitTests", "test\Microsoft.TestPlatform.BlameDataCollector.UnitTests\Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj", "{67AEC962-14ED-4432-86BF-14F3381D2B2F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests", "test\Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests\Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj", "{488675EC-C8BB-40E0-AD4F-91F623D548B3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -801,18 +801,18 @@ Global {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|x64.Build.0 = Release|Any CPU {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|x86.ActiveCfg = Release|Any CPU {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A}.Release|x86.Build.0 = Release|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|x64.ActiveCfg = Debug|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|x64.Build.0 = Debug|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|x86.ActiveCfg = Debug|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Debug|x86.Build.0 = Debug|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|Any CPU.Build.0 = Release|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|x64.ActiveCfg = Release|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|x64.Build.0 = Release|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|x86.ActiveCfg = Release|Any CPU - {67AEC962-14ED-4432-86BF-14F3381D2B2F}.Release|x86.Build.0 = Release|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Debug|x64.ActiveCfg = Debug|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Debug|x64.Build.0 = Debug|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Debug|x86.ActiveCfg = Debug|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Debug|x86.Build.0 = Debug|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|Any CPU.Build.0 = Release|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|x64.ActiveCfg = Release|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|x64.Build.0 = Release|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|x86.ActiveCfg = Release|Any CPU + {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -880,6 +880,6 @@ Global {FBF74C8F-695C-4967-84AC-358EEFB1376D} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {11ECCB8B-6958-42A7-BD58-88C09CB149B2} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} - {67AEC962-14ED-4432-86BF-14F3381D2B2F} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} + {488675EC-C8BB-40E0-AD4F-91F623D548B3} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} EndGlobalSection EndGlobal diff --git a/scripts/build.ps1 b/scripts/build.ps1 index c4032406a4..afba1b15f1 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -268,7 +268,7 @@ function Publish-Package } # Publish Datacollector - $blameDataCollector = Join-Path $env:TP_ROOT_DIR "src\Microsoft.TestPlatform.BlameDataCollector\bin\$TPB_Configuration" + $blameDataCollector = Join-Path $env:TP_ROOT_DIR "src\Microsoft.TestPlatform.Extensions.BlameDataCollector\bin\$TPB_Configuration" $blameDataCollectorNet46 = Join-Path $blameDataCollector $TPB_TargetFramework $blameDataCollectorNetCore = Join-Path $blameDataCollector $TPB_TargetFrameworkCore Copy-Item $blameDataCollectorNet46\* $fullCLRExtensionsDir -Force diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Friends.cs b/src/Microsoft.TestPlatform.BlameDataCollector/Friends.cs deleted file mode 100644 index 18ce328da5..0000000000 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Friends.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Runtime.CompilerServices; - -#region Product Assemblies - -#endregion - -#region Test Assemblies - -[assembly: InternalsVisibleTo("Microsoft.TestPlatform.BlameDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] - -#endregion diff --git a/src/Microsoft.TestPlatform.Common/Friends.cs b/src/Microsoft.TestPlatform.Common/Friends.cs index 430177d5fc..950f802108 100644 --- a/src/Microsoft.TestPlatform.Common/Friends.cs +++ b/src/Microsoft.TestPlatform.Common/Friends.cs @@ -22,6 +22,6 @@ [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] [assembly: InternalsVisibleTo("Microsoft.TestPlatform.CommunicationUtilities.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.TestPlatform.Client.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] -[assembly: InternalsVisibleTo("Microsoft.TestPlatform.BlameDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] #endregion \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs index 4d7f92b5e3..73ecadf8bb 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/BlameCollector.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs @@ -1,17 +1,22 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace Microsoft.TestPlatform.BlameDataCollector +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector { using System; using System.Collections.Generic; using System.IO; + using System.Linq; using System.Xml; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; + /// + /// The blame collector. + /// [DataCollectorFriendlyName("Blame")] - [DataCollectorTypeUri("datacollector://microsoft/blame/1.0")] + [DataCollectorTypeUri("datacollector://Microsoft/TestPlatform/Extensions/Blame")] public class BlameCollector : DataCollector, ITestExecutionEnvironmentSpecifier { private DataCollectionSink dataCollectionSink; @@ -23,7 +28,7 @@ public class BlameCollector : DataCollector, ITestExecutionEnvironmentSpecifier private int testEndCount; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// Using XmlReaderWriter by default /// public BlameCollector() @@ -32,10 +37,12 @@ public BlameCollector() } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// BlameReaderWriter instance. - public BlameCollector(IBlameReaderWriter blameReaderWriter) + /// + /// BlameReaderWriter instance. + /// + protected BlameCollector(IBlameReaderWriter blameReaderWriter) { this.blameReaderWriter = blameReaderWriter; } @@ -46,7 +53,7 @@ public BlameCollector(IBlameReaderWriter blameReaderWriter) /// Environment variables that should be set in the test execution environment public IEnumerable> GetTestExecutionEnvironmentVariables() { - return new List> { }; + return Enumerable.Empty>(); } /// @@ -57,40 +64,48 @@ public IEnumerable> GetTestExecutionEnvironmentVari /// A data collection sink for data transfer /// Data Collection Logger to send messages to the client /// Context of data collector environment - public override void Initialize(XmlElement configurationElement, - DataCollectionEvents events, DataCollectionSink dataSink, - DataCollectionLogger logger, DataCollectionEnvironmentContext environmentContext) + public override void Initialize( + XmlElement configurationElement, + DataCollectionEvents events, + DataCollectionSink dataSink, + DataCollectionLogger logger, + DataCollectionEnvironmentContext environmentContext) { ValidateArg.NotNull(logger, nameof(logger)); this.events = events; this.dataCollectionSink = dataSink; this.context = environmentContext; - testSequence = new List(); + this.testSequence = new List(); // Subscribing to events this.events.SessionEnd += this.SessionEnded_Handler; - this.events.TestCaseStart += this.Events_TestCaseStart; - this.events.TestCaseEnd += this.Events_TestCaseEnd; + this.events.TestCaseStart += this.EventsTestCaseStart; + this.events.TestCaseEnd += this.EventsTestCaseEnd; } /// /// Called when Test Case Start event is invoked /// - private void Events_TestCaseStart(object sender, TestCaseStartEventArgs e) + private void EventsTestCaseStart(object sender, TestCaseStartEventArgs e) { - EqtTrace.Info("Blame Collector : Test Case Start"); - TestCase testcase = new TestCase(e.TestElement.FullyQualifiedName, e.TestElement.ExecutorUri, e.TestElement.Source); - this.testSequence.Add(testcase); + if(EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("Blame Collector : Test Case Start"); + } + this.testSequence.Add(e.TestElement); this.testStartCount++; } /// /// Called when Test Case End event is invoked /// - private void Events_TestCaseEnd(object sender, TestCaseEndEventArgs e) + private void EventsTestCaseEnd(object sender, TestCaseEndEventArgs e) { - EqtTrace.Info("Blame Collector : Test Case End"); + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("Blame Collector : Test Case End"); + } this.testEndCount++; } @@ -99,17 +114,22 @@ private void Events_TestCaseEnd(object sender, TestCaseEndEventArgs e) /// private void SessionEnded_Handler(object sender, SessionEndEventArgs args) { - EqtTrace.Info("Blame Collector : Session End"); - + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("Blame Collector : Session End"); + } + // If the last test crashes, it will not invoke a test case end and therefore // In case of crash testStartCount will be greater than testEndCount and we need to send write the sequence if (this.testStartCount > this.testEndCount) { var filepath = Path.Combine(AppContext.BaseDirectory, Constants.AttachmentFileName); filepath = this.blameReaderWriter.WriteTestSequence(this.testSequence, filepath); - this.dataCollectionSink.SendFileAsync(this.context.SessionDataCollectionContext, filepath, true); + var fileTranferInformation = new FileTransferInformation(this.context.SessionDataCollectionContext, filepath, true); + this.dataCollectionSink.SendFileAsync(fileTranferInformation); } - DeregisterEvents(); + + this.DeregisterEvents(); } /// @@ -118,30 +138,8 @@ private void SessionEnded_Handler(object sender, SessionEndEventArgs args) private void DeregisterEvents() { this.events.SessionEnd -= this.SessionEnded_Handler; - this.events.TestCaseStart -= this.Events_TestCaseStart; - this.events.TestCaseEnd -= this.Events_TestCaseEnd; - } - - /// - /// Getter method - /// - internal int TestStartCount - { - get - { - return this.testStartCount; - } - } - - /// - /// Getter method - /// - internal int TestEndCount - { - get - { - return this.testEndCount; - } + this.events.TestCaseStart -= this.EventsTestCaseStart; + this.events.TestCaseEnd -= this.EventsTestCaseEnd; } } } diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameLogger.cs similarity index 60% rename from src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameLogger.cs index fcfbae5554..e1490e113f 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/BlameLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameLogger.cs @@ -1,39 +1,50 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace Microsoft.TestPlatform.BlameDataCollector +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector { + using System; + using System.Linq; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.Utilities; - using System; - using System.Collections.Generic; - using Microsoft.TestPlatform.BlameDataCollector.Resources; + /// + /// The blame logger. + /// [FriendlyName(BlameLogger.FriendlyName)] [ExtensionUri(BlameLogger.ExtensionUri)] public class BlameLogger : ITestLogger { - private readonly IBlameReaderWriter blameReaderWriter; - #region Constants /// /// Uri used to uniquely identify the Blame logger. /// - public const string ExtensionUri = "logger://Microsoft/TestPlatform/BlameLogger"; + public const string ExtensionUri = "logger://Microsoft/TestPlatform/Extensions/Blame"; /// /// Alternate user friendly string to uniquely identify the Blame logger. /// public const string FriendlyName = "Blame"; + /// + /// The blame reader writer. + /// + private readonly IBlameReaderWriter blameReaderWriter; + + /// + /// The output. + /// + private readonly IOutput output; + #endregion #region Constructor /// - /// Constructor : Default BlameReaderWriter used is XmlReaderWriter + /// Initializes a new instance of the class. /// public BlameLogger() : this(ConsoleOutput.Instance, new XmlReaderWriter()) @@ -43,20 +54,14 @@ public BlameLogger() /// /// Constructor added for testing purpose /// - /// + /// Output Instance /// BlameReaderWriter Instance - public BlameLogger(IOutput output, IBlameReaderWriter blameReaderWriter) + protected BlameLogger(IOutput output, IBlameReaderWriter blameReaderWriter) { - this.Output = output; + this.output = output; this.blameReaderWriter = blameReaderWriter; } - protected IOutput Output - { - get; - private set; - } - #endregion #region ITestLogger @@ -83,14 +88,22 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) ValidateArg.NotNull(sender, "sender"); ValidateArg.NotNull(e, "e"); - if (!e.IsAborted) return; + if (!e.IsAborted) + { + return; + } - Output.WriteLine(string.Empty, OutputLevel.Information); + this.output.WriteLine(string.Empty, OutputLevel.Information); // Gets the faulty test case if test aborted - var testCaseName = GetFaultyTestCase(e); - string reason = Resources.Resources.AbortedTestRun + testCaseName; - Output.Error(reason); + var testCaseName = this.GetFaultyTestCase(e); + if (testCaseName == string.Empty) + { + return; + } + + var reason = Resources.Resources.AbortedTestRun + testCaseName; + this.output.Error(reason); } #endregion @@ -100,23 +113,35 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) /// /// Fetches faulty test case /// + /// + /// The TestRunCompleteEventArgs. + /// + /// + /// Faulty test case name + /// private string GetFaultyTestCase(TestRunCompleteEventArgs e) { foreach (var attachmentSet in e.AttachmentSets) { if (attachmentSet.DisplayName.Equals(Constants.BlameDataCollectorName)) { - var filepath = attachmentSet.Attachments[0].Uri.LocalPath; - List testCaseList = this.blameReaderWriter.ReadTestSequence(filepath); - if (testCaseList.Count > 0) + var uriDataAttachment = attachmentSet.Attachments.LastOrDefault(); + if (uriDataAttachment != null) { - var testcase = testCaseList[testCaseList.Count - 1]; - return testcase.FullyQualifiedName; + var filepath = uriDataAttachment.Uri.LocalPath; + var testCaseList = this.blameReaderWriter.ReadTestSequence(filepath); + if (testCaseList.Count > 0) + { + var testcase = testCaseList[testCaseList.Count - 1]; + return testcase.FullyQualifiedName; + } } - return String.Empty; + + return string.Empty; } } - return String.Empty; + + return string.Empty; } #endregion diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Constants.cs similarity index 81% rename from src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Constants.cs index 83c7c24920..6c006e7073 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Constants.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Constants.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace Microsoft.TestPlatform.BlameDataCollector +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector { /// /// Class for constants used across the files. @@ -37,10 +37,5 @@ internal static class Constants /// Friendly name of the data collector /// public const string BlameDataCollectorName = "Blame"; - - /// - /// Test run Abort - /// - public const string TestRunAbortReason = "The test run was aborted because the host process crashed unexpectedly while executing test "; } } diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IBlameReaderWriter.cs similarity index 93% rename from src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IBlameReaderWriter.cs index 73d342f011..a336736085 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Interfaces/IBlameReaderWriter.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IBlameReaderWriter.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace Microsoft.TestPlatform.BlameDataCollector +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector { using Microsoft.VisualStudio.TestPlatform.ObjectModel; using System.Collections.Generic; diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj similarity index 55% rename from src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj index 3ca456c705..edf65287d3 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Microsoft.TestPlatform.BlameDataCollector.csproj +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj @@ -5,30 +5,18 @@ - Microsoft.TestPlatform.BlameDataCollector + Microsoft.TestPlatform.Extensions.BlameDataCollector - Microsoft.TestPlatform.BlameDataCollector - netcoreapp1.0;netcoreapp2.0;net46 - true - $(PackageTargetFallback);dnxcore50;netstandardapp1.0;portable-net45+win8;portable-net45+wp80+win8+wpa81+dnxcore50 - AnyCPU - - + Microsoft.TestPlatform.Extensions.BlameDataCollector + net46;netstandard1.5 - - - - true - - - true - + @@ -48,6 +36,13 @@ + + + True + True + Resources.resx + + ResXFileCodeGenerator @@ -55,4 +50,4 @@ - + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/Resources.Designer.cs similarity index 93% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.Designer.cs rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/Resources.Designer.cs index d4c0f0df92..6f8a01bbff 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.Designer.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/Resources.Designer.cs @@ -8,11 +8,10 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.TestPlatform.BlameDataCollector.Resources { +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector.Resources { using System; using System.Reflection; - - + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -40,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.TestPlatform.BlameDataCollector.Resources.Resources", typeof(Resources).GetTypeInfo().Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.TestPlatform.Extensions.BlameDataCollector.Resources.Resources", typeof(Resources).GetTypeInfo().Assembly); resourceMan = temp; } return resourceMan; @@ -60,9 +59,9 @@ internal Resources() { resourceCulture = value; } } - + /// - /// Looks up a localized string similar to The active Test Run was aborted because the host process exited unexpectedly while executing test . + /// Looks up a localized string similar to The active Test Run was aborted because the host process exited unexpectedly while executing test.. /// internal static string AbortedTestRun { get { diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.resx b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/Resources.resx similarity index 100% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/Resources.resx rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/Resources.resx diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.cs.xlf similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.cs.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.cs.xlf index 96a4b8fd93..f318e18ba5 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.cs.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - Aktivní testovací běh se přerušil. Důvod: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - Aktivní Test spuštění bylo přerušeno. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.de.xlf similarity index 64% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.de.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.de.xlf index 1f22190166..17d1941606 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.de.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - Der aktive Testlauf wurde abgebrochen. Grund: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - Aktive Testlauf wurde abgebrochen. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.es.xlf similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.es.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.es.xlf index 6dd8b25e2d..1122dc2222 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.es.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - Se ha anulado la serie de pruebas activa. Motivo: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - Se anuló la ejecución de prueba activa. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.fr.xlf similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.fr.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.fr.xlf index 09a6b51eed..6d17bfc40e 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.fr.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - La série de tests active a été abandonnée. Raison : {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - La série de tests active a été abandonnée. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.it.xlf similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.it.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.it.xlf index 624c75b5a0..4a2e407400 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.it.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - L'esecuzione dei test attivi è stata interrotta. Motivo: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - Esecuzione dei Test attiva è stata interrotta. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ja.xlf similarity index 62% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ja.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ja.xlf index 47a2308a0b..8f6ab5d58b 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ja.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - アクティブなテストの実行が中止されました。理由: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - アクティブなテストの実行は中止されました。 - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ko.xlf similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ko.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ko.xlf index 5f2220c67b..4f55dfddee 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ko.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - 활성 테스트 실행이 중단되었습니다. 이유: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - 활성 테스트 실행이 중단 되었습니다. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.pl.xlf similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pl.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.pl.xlf index 39533971a4..596179e346 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.pl.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - Aktywne uruchomienie testu zostało przerwane. Przyczyna: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - Aktywne Uruchom Test została przerwana. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf index a7c7ba5a8e..84b0fbd3e6 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.pt-BR.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - A execução de teste ativa foi anulada. Motivo: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - Execução de teste ativa foi anulada. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ru.xlf similarity index 61% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ru.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ru.xlf index 2e5eaed6d9..0e28adb505 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.ru.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - Активный тестовый запуск прерван. Причина: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - Прервано активного тестового запуска. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.tr.xlf similarity index 63% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.tr.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.tr.xlf index 5ab22f5b6c..8b2b9962d3 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.tr.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - Etkin test çalıştırması iptal edildi. Nedeni: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - Etkin Test çalışmasını iptal edildi. - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.xlf similarity index 80% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.xlf index ce938ceda9..550fadc5b3 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.xlf @@ -4,6 +4,7 @@ The active Test Run was aborted because the host process exited unexpectedly while executing test + The active Test Run was aborted because the host process exited unexpectedly while executing test diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf similarity index 64% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf index bb83a6cdbd..edd8b8990d 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.zh-Hans.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - 活动的测试运行已中止。原因: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - 活动测试运行已中止。 - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf similarity index 64% rename from src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf index 54d3c2538e..d4240dbed0 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Resources/xlf/Resources.zh-Hant.xlf @@ -1,11 +1,11 @@  - +
- 29 - 24.65 - 24.65 + 27 + 22.95 + 22.95 0 0 @@ -15,19 +15,15 @@ 0 0 0 - 29 + 27 0
The active Test Run was aborted because the host process exited unexpectedly while executing test - 使用中的測試回合已中止。原因: {0} + The active Test Run was aborted because the host process exited unexpectedly while executing test - - 活动测试运行已中止。 - - fuzzyMatch="15" wordcount="6" adjWordcount="5.1" curWordcount="5.1"
diff --git a/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/XmlReaderWriter.cs similarity index 72% rename from src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs rename to src/Microsoft.TestPlatform.Extensions.BlameDataCollector/XmlReaderWriter.cs index 69fc595278..ecedc66efa 100644 --- a/src/Microsoft.TestPlatform.BlameDataCollector/XmlReaderWriter.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/XmlReaderWriter.cs @@ -1,29 +1,43 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace Microsoft.TestPlatform.BlameDataCollector +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector { - using Microsoft.VisualStudio.TestPlatform.ObjectModel; - using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; - using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; using System.Collections.Generic; using System.IO; using System.Xml; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; + /// /// XmlReaderWriter class for reading and writing test sequences to file /// public class XmlReaderWriter : IBlameReaderWriter { + /// + /// The file helper. + /// private readonly IFileHelper fileHelper; #region Constructor - - public XmlReaderWriter() + + /// + /// Initializes a new instance of the class. + /// + internal XmlReaderWriter() : this(new FileHelper()) - { } - - public XmlReaderWriter(IFileHelper fileHelper) + { + } + + /// + /// Protected for testing purposes + /// + /// + /// The file helper. + /// + protected XmlReaderWriter(IFileHelper fileHelper) { this.fileHelper = fileHelper; } @@ -33,6 +47,12 @@ public XmlReaderWriter(IFileHelper fileHelper) /// /// Adds tests to document and saves document to file /// + /// + /// The test Sequence. + /// + /// + /// The file Path. + /// public string WriteTestSequence(List testSequence, string filePath) { ValidateArg.NotNull(testSequence, nameof(testSequence)); @@ -59,6 +79,7 @@ public string WriteTestSequence(List testSequence, string filePath) { xmlDocument.Save(stream); } + return filePath; } @@ -71,12 +92,12 @@ public List ReadTestSequence(string filePath) { ValidateArg.NotNull(filePath, nameof(filePath)); - if (!fileHelper.Exists(filePath)) + if (!this.fileHelper.Exists(filePath)) { throw new FileNotFoundException(); } - List testCaseList = new List(); + var testCaseList = new List(); try { // Reading test sequence @@ -88,9 +109,12 @@ public List ReadTestSequence(string filePath) var root = xmlDocument.LastChild; foreach (XmlNode node in root) { - TestCase testCase = new TestCase(); - testCase.FullyQualifiedName = node.Attributes[Constants.TestNameAttribute].Value; - testCase.Source = node.Attributes[Constants.TestSourceAttribute].Value; + var testCase = new TestCase + { + FullyQualifiedName = + node.Attributes[Constants.TestNameAttribute].Value, + Source = node.Attributes[Constants.TestSourceAttribute].Value + }; testCaseList.Add(testCase); } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/TransferInformation/FileTransferInformation.cs b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/TransferInformation/FileTransferInformation.cs index c5c7ae2c3b..306c722cfc 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/TransferInformation/FileTransferInformation.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/TransferInformation/FileTransferInformation.cs @@ -10,7 +10,7 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection /// Represents required and optional information needed for requesting a file transfer. /// public class FileTransferInformation : BasicTransferInformation - { + { #region Constructor /// diff --git a/src/package/sign/sign.proj b/src/package/sign/sign.proj index de78067e4a..097f03eb03 100644 --- a/src/package/sign/sign.proj +++ b/src/package/sign/sign.proj @@ -129,6 +129,7 @@ + diff --git a/src/vstest.console/Internal/ConsoleLogger.cs b/src/vstest.console/Internal/ConsoleLogger.cs index 9431446920..28ecc66c27 100644 --- a/src/vstest.console/Internal/ConsoleLogger.cs +++ b/src/vstest.console/Internal/ConsoleLogger.cs @@ -30,8 +30,6 @@ internal class ConsoleLogger : ITestLoggerWithParameters #region Constants private const string TestMessageFormattingPrefix = " "; - private const string BlameDataCollectorName = "Blame"; - /// /// Uri used to uniquely identify the console logger. /// diff --git a/src/vstest.console/Processors/CollectArgumentProcessor.cs b/src/vstest.console/Processors/CollectArgumentProcessor.cs index 69d8ccefad..5b0248e84c 100644 --- a/src/vstest.console/Processors/CollectArgumentProcessor.cs +++ b/src/vstest.console/Processors/CollectArgumentProcessor.cs @@ -87,7 +87,7 @@ internal class CollectArgumentProcessorCapabilities : BaseArgumentProcessorCapab public override HelpContentPriority HelpPriority => HelpContentPriority.CollectArgumentProcessorHelpPriority; } - + /// internal class CollectArgumentExecutor : IArgumentExecutor { @@ -114,31 +114,7 @@ public void Initialize(string argument) argument)); } - EnabledDataCollectors.Add(argument.ToLower()); - - var settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml; - if (settings == null) - { - this.runSettingsManager.AddDefaultRunSettings(); - settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml; - } - - var dataCollectionRunSettings = XmlRunSettingsUtilities.GetDataCollectionRunSettings(settings); - if (dataCollectionRunSettings == null) - { - dataCollectionRunSettings = new DataCollectionRunSettings(); - } - else - { - // By default, all data collectors present in run settings are enabled, if enabled attribute is not specified. - // So explicitely disable those data collectors and enable those which are specified. - DisableUnConfiguredDataCollectors(dataCollectionRunSettings); - } - - // Add data collectors if not already present, enable if already present. - EnableDataCollectorUsingFriendlyName(argument, dataCollectionRunSettings); - - this.runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.DataCollectionRunSettingsName, dataCollectionRunSettings.ToXml().InnerXml); + AddDataCollectorToRunSettings(argument, this.runSettingsManager); } /// @@ -195,5 +171,34 @@ private static bool DoesDataCollectorSettingsExist(string friendlyName, return false; } + + internal static void AddDataCollectorToRunSettings(string argument, IRunSettingsProvider runSettingsManager) + { + EnabledDataCollectors.Add(argument.ToLower()); + + var settings = runSettingsManager.ActiveRunSettings?.SettingsXml; + if (settings == null) + { + runSettingsManager.AddDefaultRunSettings(); + settings = runSettingsManager.ActiveRunSettings?.SettingsXml; + } + + var dataCollectionRunSettings = XmlRunSettingsUtilities.GetDataCollectionRunSettings(settings); + if (dataCollectionRunSettings == null) + { + dataCollectionRunSettings = new DataCollectionRunSettings(); + } + else + { + // By default, all data collectors present in run settings are enabled, if enabled attribute is not specified. + // So explicitely disable those data collectors and enable those which are specified. + DisableUnConfiguredDataCollectors(dataCollectionRunSettings); + } + + // Add data collectors if not already present, enable if already present. + EnableDataCollectorUsingFriendlyName(argument, dataCollectionRunSettings); + + runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.DataCollectionRunSettingsName, dataCollectionRunSettings.ToXml().InnerXml); + } } } diff --git a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs index d9aa11bb10..5b8b11fdb8 100644 --- a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs +++ b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs @@ -4,14 +4,13 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors { using System; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; - using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; - using Microsoft.VisualStudio.TestPlatform.Common.Interfaces; - using Microsoft.VisualStudio.TestPlatform.Common.Logging; using System.Diagnostics.Contracts; + using Microsoft.VisualStudio.TestPlatform.Common; - using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + using Microsoft.VisualStudio.TestPlatform.Common.Interfaces; + using Microsoft.VisualStudio.TestPlatform.Common.Logging; + + using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; internal class EnableBlameArgumentProcessor : IArgumentProcessor { @@ -91,7 +90,7 @@ internal class EnableBlameArgumentExecutor : IArgumentExecutor /// /// Blame logger and data collector friendly name /// - private static string BlameFriendlyName = "Blame"; + private static string BlameFriendlyName = "blame"; /// /// Test logger manager instance @@ -123,26 +122,10 @@ internal EnableBlameArgumentExecutor(IRunSettingsProvider runSettingsManager, Te public void Initialize(string argument) { // Add Blame Logger - this.loggerManager.UpdateLoggerList(BlameFriendlyName.ToLower(), BlameFriendlyName.ToLower(), null); + this.loggerManager.UpdateLoggerList(BlameFriendlyName, BlameFriendlyName, null); // Add Blame Data Collector - CollectArgumentExecutor.EnabledDataCollectors.Add(BlameFriendlyName.ToLower()); - - var settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml; - if (settings == null) - { - this.runSettingsManager.AddDefaultRunSettings(); - settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml; - } - - var dataCollectionRunSettings = XmlRunSettingsUtilities.GetDataCollectionRunSettings(settings); - if (dataCollectionRunSettings == null) - { - dataCollectionRunSettings = new DataCollectionRunSettings(); - } - - CollectArgumentExecutor.EnableDataCollectorUsingFriendlyName(BlameFriendlyName, dataCollectionRunSettings); - this.runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.DataCollectionRunSettingsName, dataCollectionRunSettings.ToXml().InnerXml); + CollectArgumentExecutor.AddDataCollectorToRunSettings(BlameFriendlyName, this.runSettingsManager); } /// diff --git a/src/vstest.console/Processors/EnableCodeCoverageArgumentProcessor.cs b/src/vstest.console/Processors/EnableCodeCoverageArgumentProcessor.cs index ea044fe577..1992d398a0 100644 --- a/src/vstest.console/Processors/EnableCodeCoverageArgumentProcessor.cs +++ b/src/vstest.console/Processors/EnableCodeCoverageArgumentProcessor.cs @@ -4,12 +4,8 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors { using System; - - using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities; using Microsoft.VisualStudio.TestPlatform.Common; using Microsoft.VisualStudio.TestPlatform.Common.Interfaces; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; @@ -103,24 +99,7 @@ internal EnableCodeCoverageArgumentExecutor(IRunSettingsProvider runSettingsMana public void Initialize(string argument) { // Add this enabled data collectors list, this will ensure Code Coverage isn't disabled when other DCs are configured using /Collect. - CollectArgumentExecutor.EnabledDataCollectors.Add(FriendlyName.ToLower()); - - var settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml; - if (settings == null) - { - this.runSettingsManager.AddDefaultRunSettings(); - settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml; - } - - var dataCollectionRunSettings = XmlRunSettingsUtilities.GetDataCollectionRunSettings(settings); - if (dataCollectionRunSettings == null) - { - dataCollectionRunSettings = new DataCollectionRunSettings(); - } - - CollectArgumentExecutor.EnableDataCollectorUsingFriendlyName(FriendlyName, dataCollectionRunSettings); - - this.runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.DataCollectionRunSettingsName, dataCollectionRunSettings.ToXml().InnerXml); + CollectArgumentExecutor.AddDataCollectorToRunSettings(argument, this.runSettingsManager); } /// diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj b/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj deleted file mode 100644 index 7d98632a5d..0000000000 --- a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/Microsoft.TestPlatform.BlameDataCollector.UnitTests.csproj +++ /dev/null @@ -1,56 +0,0 @@ - - - - ..\..\ - true - - - - Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests - - - netcoreapp1.0;net46 - Microsoft.TestPlatform.BlameDataCollector.UnitTests - $(PackageTargetFallback);dnxcore50;portable-net45+win8 - - - - - - - true - - - true - - - true - - - true - - - true - - - - - - - - - - - - - 4.3.0 - - - - - - - - - - diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs similarity index 52% rename from test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs rename to test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs index a97343234c..064f739580 100644 --- a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameCollectorTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs @@ -1,18 +1,23 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests { using System; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; - using Moq; - using Microsoft.TestPlatform.BlameDataCollector; + using System.Collections.Generic; + using System.IO; using System.Xml; + + using Microsoft.TestPlatform.Extensions.BlameDataCollector; using Microsoft.VisualStudio.TestPlatform.ObjectModel; - using System.IO; - using System.Collections.Generic; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; + + /// + /// The blame collector tests. + /// [TestClass] public class BlameCollectorTests { @@ -25,6 +30,9 @@ public class BlameCollectorTests private Mock mockBlameReaderWriter; private XmlElement configurationElement; + /// + /// Initializes a new instance of the class. + /// public BlameCollectorTests() { // Initializing mocks @@ -32,98 +40,105 @@ public BlameCollectorTests() this.mockDataColectionEvents = new Mock(); this.mockDataCollectionSink = new Mock(); this.mockBlameReaderWriter = new Mock(); - this.blameDataCollector = new BlameCollector(this.mockBlameReaderWriter.Object); + this.blameDataCollector = new TestableBlameCollector(this.mockBlameReaderWriter.Object); // Initializing members - TestCase testcase = new TestCase(); - testcase.Id = Guid.NewGuid(); + TestCase testcase = new TestCase { Id = Guid.NewGuid() }; this.dataCollectionContext = new DataCollectionContext(testcase); this.configurationElement = null; this.context = new DataCollectionEnvironmentContext(this.dataCollectionContext); } + /// + /// The initialize should throw exception if data collection logger is null. + /// [TestMethod] public void InitializeShouldThrowExceptionIfDataCollectionLoggerIsNull() { Assert.ThrowsException(() => - { - this.blameDataCollector.Initialize(this.configurationElement, - this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, - (DataCollectionLogger)null, null); - }); - } - - [TestMethod] - public void TriggerTestCaseStartedHandlerShouldIncreaseTestStartCount() - { - TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); - - // Initializing Blame Data Collector - this.blameDataCollector.Initialize(this.configurationElement, - this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, - this.mockLogger.Object, this.context); - - // Setup and Raise Session End Event - this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase)); - - // Assert - Assert.AreEqual(1, this.blameDataCollector.TestStartCount); - } - - [TestMethod] - public void TriggerTestCaseEndedHandlerShouldIncreaseTestEndCount() - { - TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); - - // Initializing Blame Data Collector - this.blameDataCollector.Initialize(this.configurationElement, - this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, - this.mockLogger.Object, this.context); - - // Setup and Raise Session End Event - this.mockDataColectionEvents.Raise(x => x.TestCaseEnd += null, new TestCaseEndEventArgs(testcase, TestOutcome.Passed)); - - // Assert - Assert.AreEqual(1, this.blameDataCollector.TestEndCount); + { + this.blameDataCollector.Initialize( + this.configurationElement, + this.mockDataColectionEvents.Object, + this.mockDataCollectionSink.Object, + null, + null); + }); } + /// + /// The trigger session ended handler should write to file if test start count is greater. + /// [TestMethod] public void TriggerSessionEndedHandlerShouldWriteToFileIfTestStartCountIsGreater() - { + { // Initializing Blame Data Collector - this.blameDataCollector.Initialize(this.configurationElement, - this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, - this.mockLogger.Object, this.context); - var filepath = Path.Combine(AppContext.BaseDirectory, "Sequence"); + this.blameDataCollector.Initialize( + this.configurationElement, + this.mockDataColectionEvents.Object, + this.mockDataCollectionSink.Object, + this.mockLogger.Object, + this.context); + + var filepath = Path.Combine(AppContext.BaseDirectory, "Test"); TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); + using (var fs = File.Create(filepath)) + { + } // Setup and Raise TestCaseStart and Session End Event - this.mockDataCollectionSink.Setup(x => x.SendFileAsync(It.IsAny(), It.IsAny(), It.IsAny())); + this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny>(), It.IsAny())) + .Returns(filepath); + this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase)); - this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(dataCollectionContext)); + this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext)); // Verify WriteTestSequence Call - this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), filepath), Times.Once); + this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), It.IsAny()), Times.Once); + File.Delete(filepath); } + /// + /// The trigger session ended handler should not write to file if test start count is same as test end count. + /// [TestMethod] - public void TriggerSessionEndedHandlerShouldNotWriteToTestStartCountIsSameAsTestEndCountFile() + public void TriggerSessionEndedHandlerShouldNotWriteToFileIfTestStartCountIsSameAsTestEndCount() { // Initializing Blame Data Collector - this.blameDataCollector.Initialize(this.configurationElement, - this.mockDataColectionEvents.Object, this.mockDataCollectionSink.Object, - this.mockLogger.Object, this.context); + this.blameDataCollector.Initialize( + this.configurationElement, + this.mockDataColectionEvents.Object, + this.mockDataCollectionSink.Object, + this.mockLogger.Object, + this.context); + var filepath = Path.Combine(AppContext.BaseDirectory, "TestSequence.xml"); TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); // Setup and Raise TestCaseStart and Session End Event - this.mockDataCollectionSink.Setup(x => x.SendFileAsync(It.IsAny(), It.IsAny(), It.IsAny())); this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase)); this.mockDataColectionEvents.Raise(x => x.TestCaseEnd += null, new TestCaseEndEventArgs(testcase, TestOutcome.Passed)); - this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(dataCollectionContext)); + this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext)); // Verify WriteTestSequence Call this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), filepath), Times.Never); } + + /// + /// The testable blame collector. + /// + internal class TestableBlameCollector : BlameCollector + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The blame reader writer. + /// + internal TestableBlameCollector(IBlameReaderWriter blameReaderWriter) + : base(blameReaderWriter) + { + } + } } } diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameLoggerTests.cs similarity index 53% rename from test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs rename to test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameLoggerTests.cs index 9cf4ca41c7..e05232406f 100644 --- a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/BlameLoggerTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameLoggerTests.cs @@ -1,19 +1,24 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests { - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.TestPlatform.BlameDataCollector; using System; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; - using Moq; - using Microsoft.VisualStudio.TestPlatform.Utilities; - using Microsoft.VisualStudio.TestPlatform.Common.Logging; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using System.Collections.Generic; using System.Collections.ObjectModel; + using Microsoft.TestPlatform.Extensions.BlameDataCollector; + using Microsoft.VisualStudio.TestPlatform.Common.Logging; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.Utilities; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + using Moq; + + /// + /// The blame logger tests. + /// [TestClass] public class BlameLoggerTests { @@ -24,7 +29,9 @@ public class BlameLoggerTests private TestLoggerManager testLoggerManager; private BlameLogger blameLogger; - + /// + /// Initializes a new instance of the class. + /// public BlameLoggerTests() { // Mock for ITestRunRequest @@ -32,10 +39,10 @@ public BlameLoggerTests() this.events = new Mock(); this.mockOutput = new Mock(); this.mockBlameReaderWriter = new Mock(); - this.blameLogger = new BlameLogger(this.mockOutput.Object, mockBlameReaderWriter.Object); + this.blameLogger = new TestableBlameLogger(this.mockOutput.Object, this.mockBlameReaderWriter.Object); // Create Instance of TestLoggerManager - this.testLoggerManager = new DummyTestLoggerManager(); + this.testLoggerManager = new TestableTestLoggerManager(); this.testLoggerManager.AddLogger(this.blameLogger, BlameLogger.ExtensionUri, null); this.testLoggerManager.EnableLogging(); @@ -43,6 +50,9 @@ public BlameLoggerTests() this.testLoggerManager.RegisterTestRunEvents(this.testRunRequest.Object); } + /// + /// The initialize should throw exception if events is null. + /// [TestMethod] public void InitializeShouldThrowExceptionIfEventsIsNull() { @@ -52,6 +62,9 @@ public void InitializeShouldThrowExceptionIfEventsIsNull() }); } + /// + /// The test result complete handler should throw exception if event args is null. + /// [TestMethod] public void TestResultCompleteHandlerShouldThrowExceptionIfEventArgsIsNull() { @@ -62,6 +75,9 @@ public void TestResultCompleteHandlerShouldThrowExceptionIfEventArgsIsNull() }); } + /// + /// The test run complete handler should get faulty test run if test run aborted. + /// [TestMethod] public void TestRunCompleteHandlerShouldGetFaultyTestRunIfTestRunAborted() { @@ -69,15 +85,17 @@ public void TestRunCompleteHandlerShouldGetFaultyTestRunIfTestRunAborted() var attachmentSet = new AttachmentSet(new Uri("test://uri"), "Blame"); var uriDataAttachment = new UriDataAttachment(new Uri("C:/folder1/sequence.xml"), "description"); attachmentSet.Attachments.Add(uriDataAttachment); - var attachmentSetList = new List(); - attachmentSetList.Add(attachmentSet); + var attachmentSetList = new List { attachmentSet }; // Initialize Blame Logger this.blameLogger.Initialize(this.events.Object, null); - List testCaseList = new List(); - testCaseList.Add(new TestCase("ABC.UnitTestMethod1", new Uri("test://uri"), "C://test/filepath")); - testCaseList.Add(new TestCase("ABC.UnitTestMethod2", new Uri("test://uri"), "C://test/filepath")); + var testCaseList = + new List + { + new TestCase("ABC.UnitTestMethod1", new Uri("test://uri"), "C://test/filepath"), + new TestCase("ABC.UnitTestMethod2", new Uri("test://uri"), "C://test/filepath") + }; // Setup and Raise event this.mockBlameReaderWriter.Setup(x => x.ReadTestSequence(It.IsAny())).Returns(testCaseList); @@ -89,6 +107,9 @@ public void TestRunCompleteHandlerShouldGetFaultyTestRunIfTestRunAborted() this.mockBlameReaderWriter.Verify(x => x.ReadTestSequence(It.IsAny()), Times.Once); } + /// + /// The test run complete handler should not read file if test run not aborted. + /// [TestMethod] public void TestRunCompleteHandlerShouldNotReadFileIfTestRunNotAborted() { @@ -105,9 +126,57 @@ public void TestRunCompleteHandlerShouldNotReadFileIfTestRunNotAborted() this.mockBlameReaderWriter.Verify(x => x.ReadTestSequence(It.IsAny()), Times.Never); } - internal class DummyTestLoggerManager : TestLoggerManager + /// + /// The test run complete handler should return if uri attachment is null. + /// + [TestMethod] + public void TestRunCompleteHandlerShouldReturnIfUriAttachmentIsNull() + { + // Initialize + var attachmentSet = new AttachmentSet(new Uri("test://uri"), "Blame"); + var attachmentSetList = new List { attachmentSet }; + + // Initialize Blame Logger + this.blameLogger.Initialize(this.events.Object, null); + + // Setup and Raise event + this.testRunRequest.Raise( + m => m.OnRunCompletion += null, + new TestRunCompleteEventArgs(stats: null, isCanceled: false, isAborted: true, error: null, attachmentSets: new Collection(attachmentSetList), elapsedTime: new TimeSpan(1, 0, 0, 0))); + + // Verify Call + this.mockBlameReaderWriter.Verify(x => x.ReadTestSequence(It.IsAny()), Times.Never); + } + + /// + /// The testable test logger manager. + /// + internal class TestableTestLoggerManager : TestLoggerManager + { + /// + /// Initializes a new instance of the class. + /// + internal TestableTestLoggerManager() : base(TestSessionMessageLogger.Instance, new InternalTestLoggerEvents(TestSessionMessageLogger.Instance)) + { + } + } + + /// + /// The testable blame logger. + /// + internal class TestableBlameLogger : BlameLogger { - public DummyTestLoggerManager() : base(TestSessionMessageLogger.Instance, new InternalTestLoggerEvents(TestSessionMessageLogger.Instance)) + /// + /// Initializes a new instance of the class. + /// + /// + /// The output. + /// + /// + /// The blame Reader Writer. + /// + internal TestableBlameLogger(IOutput output, IBlameReaderWriter blameReaderWriter) + : base(output, blameReaderWriter) { } } diff --git a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj new file mode 100644 index 0000000000..bb5e50e93c --- /dev/null +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj @@ -0,0 +1,39 @@ + + + + ..\..\ + true + + + + Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests + + + netcoreapp1.0;net46 + Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests + + + + + true + + + + + + + + + + + 4.3.0 + + + + + + + + + + diff --git a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs similarity index 60% rename from test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs rename to test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs index 0296977b23..b84f6b0e66 100644 --- a/test/Microsoft.TestPlatform.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs @@ -1,70 +1,79 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.IO; - -namespace Microsoft.VisualStudio.TestPlatform.BlameDataCollector.UnitTests +namespace Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests { using System; using System.Collections.Generic; - using Microsoft.TestPlatform.BlameDataCollector; + using System.IO; + + using Microsoft.TestPlatform.Extensions.BlameDataCollector; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; + /// + /// The xml reader writer tests. + /// [TestClass] public class XmlReaderWriterTests { - private XmlReaderWriter xmlReaderWriter; + private TestableXmlReaderWriter xmlReaderWriter; private Mock mockFileHelper; private Mock mockStream; + List testCaseList; + private TestCase testcase; - + /// + /// Initializes a new instance of the class. + /// public XmlReaderWriterTests() { this.mockFileHelper = new Mock(); - this.xmlReaderWriter = new XmlReaderWriter(this.mockFileHelper.Object); + this.xmlReaderWriter = new TestableXmlReaderWriter(this.mockFileHelper.Object); this.mockStream = new Mock(); - - } - - [TestMethod] - public void WriteTestSequenceShouldThrowExceptionIfFilePathIsNull() - { - TestCase testcase = new TestCase + this.testCaseList = new List(); + this.testcase = new TestCase { Id = Guid.NewGuid(), FullyQualifiedName = "TestProject.UnitTest.TestMethod", Source = "abc.dll" }; - List testSequence = new List(); - testSequence.Add(testcase); + } + + /// + /// The write test sequence should throw exception if file path is null. + /// + [TestMethod] + public void WriteTestSequenceShouldThrowExceptionIfFilePathIsNull() + { + this.testCaseList.Add(this.testcase); Assert.ThrowsException(() => { - this.xmlReaderWriter.WriteTestSequence(testSequence, null); + this.xmlReaderWriter.WriteTestSequence(this.testCaseList, null); }); } + /// + /// The write test sequence should throw exception if file path is empty. + /// [TestMethod] public void WriteTestSequenceShouldThrowExceptionIfFilePathIsEmpty() { - TestCase testcase = new TestCase - { - Id = Guid.NewGuid(), - FullyQualifiedName = "TestProject.UnitTest.TestMethod", - Source = "abc.dll" - }; - List testSequence = new List(); - testSequence.Add(testcase); + this.testCaseList.Add(this.testcase); Assert.ThrowsException(() => { - this.xmlReaderWriter.WriteTestSequence(testSequence, String.Empty); + this.xmlReaderWriter.WriteTestSequence(this.testCaseList, string.Empty); }); } + /// + /// The read test sequence should throw exception if file path is null. + /// [TestMethod] public void ReadTestSequenceShouldThrowExceptionIfFilePathIsNull() { @@ -74,6 +83,9 @@ public void ReadTestSequenceShouldThrowExceptionIfFilePathIsNull() }); } + /// + /// The read test sequence should throw exception if file not found. + /// [TestMethod] public void ReadTestSequenceShouldThrowExceptionIfFileNotFound() { @@ -81,10 +93,13 @@ public void ReadTestSequenceShouldThrowExceptionIfFileNotFound() Assert.ThrowsException(() => { - this.xmlReaderWriter.ReadTestSequence(String.Empty); + this.xmlReaderWriter.ReadTestSequence(string.Empty); }); } + /// + /// The read test sequence should read file stream. + /// [TestMethod] public void ReadTestSequenceShouldReadFileStream() { @@ -103,18 +118,19 @@ public void ReadTestSequenceShouldReadFileStream() } + /// + /// The write test sequence should write file stream. + /// [TestMethod] public void WriteTestSequenceShouldWriteFileStream() { - List testCaseList = new List(); - // Setup this.mockFileHelper.Setup(m => m.Exists(It.IsAny())).Returns(true); this.mockFileHelper.Setup(m => m.GetStream("path.xml", FileMode.Create, FileAccess.ReadWrite)).Returns(this.mockStream.Object); this.mockStream.Setup(x => x.CanWrite).Returns(true); this.mockStream.Setup(x => x.Write(It.IsAny(), It.IsAny(), It.IsAny())); - this.xmlReaderWriter.WriteTestSequence(testCaseList, "path"); + this.xmlReaderWriter.WriteTestSequence(this.testCaseList, "path"); // Verify Call to fileHelper this.mockFileHelper.Verify(x => x.GetStream("path.xml", FileMode.Create, FileAccess.ReadWrite)); @@ -122,5 +138,22 @@ public void WriteTestSequenceShouldWriteFileStream() // Verify Call to stream write this.mockStream.Verify(x => x.Write(It.IsAny(), It.IsAny(), It.IsAny())); } + + /// + /// The testable xml reader writer. + /// + internal class TestableXmlReaderWriter : XmlReaderWriter + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The file helper. + /// + internal TestableXmlReaderWriter(IFileHelper fileHelper) + : base(fileHelper) + { + } + } } } diff --git a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs index fee6dae7e5..669a7b84c8 100644 --- a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs @@ -1,10 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; - namespace vstest.console.UnitTests.Processors { + using System; using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors; using Microsoft.VisualStudio.TestPlatform.Common; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -68,7 +67,7 @@ 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 \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); } [TestMethod] diff --git a/test/vstest.console.UnitTests/Processors/EnableCodeCoverageArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableCodeCoverageArgumentProcessorTests.cs index 4bfc6efa32..8427155cfb 100644 --- a/test/vstest.console.UnitTests/Processors/EnableCodeCoverageArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableCodeCoverageArgumentProcessorTests.cs @@ -87,6 +87,7 @@ public void InitializeShouldEnableCodeCoverageIfDisabledInRunSettings() [TestMethod] public void InitializeShouldNotDisableOtherDataCollectors() { + CollectArgumentExecutor.EnabledDataCollectors.Add("mydatacollector1"); var runsettingsString = string.Format(DefaultRunSettings, ""); var runsettings = new RunSettings(); runsettings.LoadSettingsXml(runsettingsString); From 6922cb9525e9b8e6ceb3cd98528c5b2679864f02 Mon Sep 17 00:00:00 2001 From: t-vanidh Date: Sat, 8 Jul 2017 18:57:12 +0530 Subject: [PATCH 4/9] Spaces removed --- .../DataCollector/DataCollectionSink.cs | 2 +- .../TransferInformation/FileTransferInformation.cs | 2 +- src/vstest.console/Internal/ConsoleLogger.cs | 8 ++------ src/vstest.console/Processors/CollectArgumentProcessor.cs | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/DataCollectionSink.cs b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/DataCollectionSink.cs index 944f4a6959..0ba739b967 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/DataCollectionSink.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/DataCollectionSink.cs @@ -39,7 +39,7 @@ protected DataCollectionSink() /// The context in which the file is being sent. Cannot be null. /// the path to the file on the local file system /// True to automatically have the file removed after sending it. - public virtual void SendFileAsync(DataCollectionContext context, string path, bool deleteFile) + public void SendFileAsync(DataCollectionContext context, string path, bool deleteFile) { this.SendFileAsync(context, path, string.Empty, deleteFile); } diff --git a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/TransferInformation/FileTransferInformation.cs b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/TransferInformation/FileTransferInformation.cs index 306c722cfc..c5c7ae2c3b 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/TransferInformation/FileTransferInformation.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/TransferInformation/FileTransferInformation.cs @@ -10,7 +10,7 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection /// Represents required and optional information needed for requesting a file transfer. /// public class FileTransferInformation : BasicTransferInformation - { + { #region Constructor /// diff --git a/src/vstest.console/Internal/ConsoleLogger.cs b/src/vstest.console/Internal/ConsoleLogger.cs index 28ecc66c27..29677ff6aa 100644 --- a/src/vstest.console/Internal/ConsoleLogger.cs +++ b/src/vstest.console/Internal/ConsoleLogger.cs @@ -390,16 +390,12 @@ private void TestResultHandler(object sender, TestResultEventArgs e) private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) { Output.WriteLine(string.Empty, OutputLevel.Information); + + // Printing Run-level Attachments var runLevelAttachementCount = (e.AttachmentSets == null) ? 0 : e.AttachmentSets.Sum(attachmentSet => attachmentSet.Attachments.Count); - - // Printing Run-level Attachments if (runLevelAttachementCount > 0) { Output.Information(CommandLineResources.AttachmentsBanner); - } - - if (runLevelAttachementCount > 0) - { foreach (var attachmentSet in e.AttachmentSets) { foreach (var uriDataAttachment in attachmentSet.Attachments) diff --git a/src/vstest.console/Processors/CollectArgumentProcessor.cs b/src/vstest.console/Processors/CollectArgumentProcessor.cs index 5b0248e84c..97e40171f3 100644 --- a/src/vstest.console/Processors/CollectArgumentProcessor.cs +++ b/src/vstest.console/Processors/CollectArgumentProcessor.cs @@ -87,7 +87,7 @@ internal class CollectArgumentProcessorCapabilities : BaseArgumentProcessorCapab public override HelpContentPriority HelpPriority => HelpContentPriority.CollectArgumentProcessorHelpPriority; } - + /// internal class CollectArgumentExecutor : IArgumentExecutor { From 1e9b6cad2d6ef16b7e6a8f3eb1d6ce6c1bccb384 Mon Sep 17 00:00:00 2001 From: t-vanidh Date: Mon, 10 Jul 2017 11:34:26 +0530 Subject: [PATCH 5/9] Build updated --- scripts/build.ps1 | 5 +++-- src/vstest.console/Internal/ConsoleLogger.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index afba1b15f1..e69b9cd6b6 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -268,11 +268,12 @@ function Publish-Package } # Publish Datacollector + $TPB_TargetFrameworkStandard = "netstandard1.5" $blameDataCollector = Join-Path $env:TP_ROOT_DIR "src\Microsoft.TestPlatform.Extensions.BlameDataCollector\bin\$TPB_Configuration" $blameDataCollectorNet46 = Join-Path $blameDataCollector $TPB_TargetFramework - $blameDataCollectorNetCore = Join-Path $blameDataCollector $TPB_TargetFrameworkCore + $blameDataCollectorNetStandard = Join-Path $blameDataCollector $TPB_TargetFrameworkStandard Copy-Item $blameDataCollectorNet46\* $fullCLRExtensionsDir -Force - Copy-Item $blameDataCollectorNetCore\* $coreCLRExtensionsDir -Force + Copy-Item $blameDataCollectorNetStandard\* $coreCLRExtensionsDir -Force # Note Note: If there are some dependencies for the TestHostRuntimeProvider assemblies, those need to be moved too. $runtimeproviders = @("Microsoft.TestPlatform.TestHostRuntimeProvider.dll", "Microsoft.TestPlatform.TestHostRuntimeProvider.pdb") diff --git a/src/vstest.console/Internal/ConsoleLogger.cs b/src/vstest.console/Internal/ConsoleLogger.cs index 29677ff6aa..7ebbe94c00 100644 --- a/src/vstest.console/Internal/ConsoleLogger.cs +++ b/src/vstest.console/Internal/ConsoleLogger.cs @@ -391,7 +391,7 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) { Output.WriteLine(string.Empty, OutputLevel.Information); - // Printing Run-level Attachments + // Printing Run-level Attachments var runLevelAttachementCount = (e.AttachmentSets == null) ? 0 : e.AttachmentSets.Sum(attachmentSet => attachmentSet.Attachments.Count); if (runLevelAttachementCount > 0) { From 1d352f30bee2aa1d9ab960833a06f79c942f6f00 Mon Sep 17 00:00:00 2001 From: t-vanidh Date: Wed, 12 Jul 2017 21:54:58 +0530 Subject: [PATCH 6/9] Integration test added --- TestPlatform.sln | 15 ++++ .../BlameCollector.cs | 57 +++++++++--- .../BlameLogger.cs | 25 ++++-- .../Constants.cs | 2 +- .../Interfaces/IBlameReaderWriter.cs | 3 +- ...tform.Extensions.BlameDataCollector.csproj | 4 +- .../XmlReaderWriter.cs | 9 +- src/package/sign/sign.proj | 2 + .../EnableBlameArgumentProcessor.cs | 56 +++++++++++- .../BlameDataCollectorTests.cs | 88 +++++++++++++++++++ .../BlameCollectorTests.cs | 28 +++--- .../BlameLoggerTests.cs | 9 +- ...nsions.BlameDataCollector.UnitTests.csproj | 2 + .../XmlReaderWriterTests.cs | 3 +- .../BlameUnitTestProject.csproj | 31 +++++++ .../BlameUnitTestProject/UnitTest1.cs | 26 ++++++ .../EnableBlameArgumentProcessorTests.cs | 6 +- 17 files changed, 318 insertions(+), 48 deletions(-) create mode 100644 test/Microsoft.TestPlatform.AcceptanceTests/BlameDataCollectorTests.cs create mode 100644 test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj create mode 100644 test/TestAssets/BlameUnitTestProject/UnitTest1.cs diff --git a/TestPlatform.sln b/TestPlatform.sln index 363ab8f621..d917217c24 100644 --- a/TestPlatform.sln +++ b/TestPlatform.sln @@ -155,6 +155,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Exte EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests", "test\Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests\Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj", "{488675EC-C8BB-40E0-AD4F-91F623D548B3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlameUnitTestProject", "test\TestAssets\BlameUnitTestProject\BlameUnitTestProject.csproj", "{6B2B841C-CCFF-469A-9939-EB07EA0401AE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -813,6 +815,18 @@ Global {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|x64.Build.0 = Release|Any CPU {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|x86.ActiveCfg = Release|Any CPU {488675EC-C8BB-40E0-AD4F-91F623D548B3}.Release|x86.Build.0 = Release|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Debug|x64.ActiveCfg = Debug|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Debug|x64.Build.0 = Debug|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Debug|x86.ActiveCfg = Debug|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Debug|x86.Build.0 = Debug|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Release|Any CPU.Build.0 = Release|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Release|x64.ActiveCfg = Release|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Release|x64.Build.0 = Release|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Release|x86.ActiveCfg = Release|Any CPU + {6B2B841C-CCFF-469A-9939-EB07EA0401AE}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -881,5 +895,6 @@ Global {11ECCB8B-6958-42A7-BD58-88C09CB149B2} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {488675EC-C8BB-40E0-AD4F-91F623D548B3} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} + {6B2B841C-CCFF-469A-9939-EB07EA0401AE} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A} EndGlobalSection EndGlobal diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs index 73ecadf8bb..59631fa941 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameCollector.cs @@ -8,7 +8,6 @@ namespace Microsoft.TestPlatform.Extensions.BlameDataCollector using System.IO; using System.Linq; using System.Xml; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; @@ -16,7 +15,7 @@ namespace Microsoft.TestPlatform.Extensions.BlameDataCollector /// The blame collector. /// [DataCollectorFriendlyName("Blame")] - [DataCollectorTypeUri("datacollector://Microsoft/TestPlatform/Extensions/Blame")] + [DataCollectorTypeUri("datacollector://Microsoft/TestPlatform/Extensions/Blame/v1")] public class BlameCollector : DataCollector, ITestExecutionEnvironmentSpecifier { private DataCollectionSink dataCollectionSink; @@ -24,11 +23,12 @@ public class BlameCollector : DataCollector, ITestExecutionEnvironmentSpecifier private DataCollectionEvents events; private List testSequence; private IBlameReaderWriter blameReaderWriter; + private XmlElement configurationElement; private int testStartCount; private int testEndCount; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// Using XmlReaderWriter by default /// public BlameCollector() @@ -37,7 +37,7 @@ public BlameCollector() } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// BlameReaderWriter instance. @@ -66,9 +66,9 @@ public IEnumerable> GetTestExecutionEnvironmentVari /// Context of data collector environment public override void Initialize( XmlElement configurationElement, - DataCollectionEvents events, + DataCollectionEvents events, DataCollectionSink dataSink, - DataCollectionLogger logger, + DataCollectionLogger logger, DataCollectionEnvironmentContext environmentContext) { ValidateArg.NotNull(logger, nameof(logger)); @@ -76,6 +76,7 @@ public override void Initialize( this.events = events; this.dataCollectionSink = dataSink; this.context = environmentContext; + this.configurationElement = configurationElement; this.testSequence = new List(); // Subscribing to events @@ -85,33 +86,41 @@ public override void Initialize( } /// - /// Called when Test Case Start event is invoked + /// Called when Test Case Start event is invoked /// + /// Sender + /// TestCaseStartEventArgs private void EventsTestCaseStart(object sender, TestCaseStartEventArgs e) { - if(EqtTrace.IsInfoEnabled) + if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("Blame Collector : Test Case Start"); } + this.testSequence.Add(e.TestElement); this.testStartCount++; } /// - /// Called when Test Case End event is invoked + /// Called when Test Case End event is invoked /// + /// Sender + /// TestCaseEndEventArgs private void EventsTestCaseEnd(object sender, TestCaseEndEventArgs e) { if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("Blame Collector : Test Case End"); - } + } + this.testEndCount++; } /// - /// Called when Session End event is invoked + /// Called when Session End event is invoked /// + /// Sender + /// SessionEndEventArgs private void SessionEnded_Handler(object sender, SessionEndEventArgs args) { if (EqtTrace.IsInfoEnabled) @@ -119,11 +128,12 @@ private void SessionEnded_Handler(object sender, SessionEndEventArgs args) EqtTrace.Info("Blame Collector : Session End"); } - // If the last test crashes, it will not invoke a test case end and therefore - // In case of crash testStartCount will be greater than testEndCount and we need to send write the sequence + // If the last test crashes, it will not invoke a test case end and therefore + // In case of crash testStartCount will be greater than testEndCount and we need to write the sequence + // And send the attachment if (this.testStartCount > this.testEndCount) { - var filepath = Path.Combine(AppContext.BaseDirectory, Constants.AttachmentFileName); + var filepath = Path.Combine(this.GetResultsDirectory(), Constants.AttachmentFileName); filepath = this.blameReaderWriter.WriteTestSequence(this.testSequence, filepath); var fileTranferInformation = new FileTransferInformation(this.context.SessionDataCollectionContext, filepath, true); this.dataCollectionSink.SendFileAsync(fileTranferInformation); @@ -141,5 +151,24 @@ private void DeregisterEvents() this.events.TestCaseStart -= this.EventsTestCaseStart; this.events.TestCaseEnd -= this.EventsTestCaseEnd; } + + private string GetResultsDirectory() + { + try + { + XmlElement resultsDirectoryElement = this.configurationElement["ResultsDirectory"]; + string resultsDirectory = resultsDirectoryElement != null ? resultsDirectoryElement.InnerText : string.Empty; + return resultsDirectory; + } + catch (NullReferenceException exception) + { + if (EqtTrace.IsErrorEnabled) + { + EqtTrace.Error("Blame Collector : " + exception); + } + + return string.Empty; + } + } } } diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameLogger.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameLogger.cs index e1490e113f..add5ff88a5 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/BlameLogger.cs @@ -22,7 +22,7 @@ public class BlameLogger : ITestLogger /// /// Uri used to uniquely identify the Blame logger. /// - public const string ExtensionUri = "logger://Microsoft/TestPlatform/Extensions/Blame"; + public const string ExtensionUri = "logger://Microsoft/TestPlatform/Extensions/Blame/v1"; /// /// Alternate user friendly string to uniquely identify the Blame logger. @@ -39,12 +39,12 @@ public class BlameLogger : ITestLogger /// private readonly IOutput output; - #endregion + #endregion #region Constructor /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public BlameLogger() : this(ConsoleOutput.Instance, new XmlReaderWriter()) @@ -52,6 +52,7 @@ public BlameLogger() } /// + /// Initializes a new instance of the class. /// Constructor added for testing purpose /// /// Output Instance @@ -77,14 +78,22 @@ public void Initialize(TestLoggerEvents events, string testRunDictionary) { throw new ArgumentNullException(nameof(events)); } + events.TestRunComplete += this.TestRunCompleteHandler; } /// /// Called when a test run is complete. /// + /// Sender + /// TestRunCompleteEventArgs private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) { + if (sender == null) + { + throw new ArgumentNullException(nameof(sender)); + } + ValidateArg.NotNull(sender, "sender"); ValidateArg.NotNull(e, "e"); @@ -95,13 +104,13 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) this.output.WriteLine(string.Empty, OutputLevel.Information); - // Gets the faulty test case if test aborted + // Gets the faulty test case if test aborted var testCaseName = this.GetFaultyTestCase(e); if (testCaseName == string.Empty) { return; } - + var reason = Resources.Resources.AbortedTestRun + testCaseName; this.output.Error(reason); } @@ -109,7 +118,7 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) #endregion #region Faulty test case fetch - + /// /// Fetches faulty test case /// @@ -132,7 +141,7 @@ private string GetFaultyTestCase(TestRunCompleteEventArgs e) var testCaseList = this.blameReaderWriter.ReadTestSequence(filepath); if (testCaseList.Count > 0) { - var testcase = testCaseList[testCaseList.Count - 1]; + var testcase = testCaseList.Last(); return testcase.FullyQualifiedName; } } @@ -143,7 +152,7 @@ private string GetFaultyTestCase(TestRunCompleteEventArgs e) return string.Empty; } - + #endregion } } diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Constants.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Constants.cs index 6c006e7073..d4ea047a87 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Constants.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Constants.cs @@ -32,7 +32,7 @@ internal static class Constants /// Test Source Attribute. /// public const string TestSourceAttribute = "Source"; - + /// /// Friendly name of the data collector /// diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IBlameReaderWriter.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IBlameReaderWriter.cs index a336736085..e8b2d3a996 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IBlameReaderWriter.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Interfaces/IBlameReaderWriter.cs @@ -3,8 +3,8 @@ namespace Microsoft.TestPlatform.Extensions.BlameDataCollector { - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using System.Collections.Generic; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; public interface IBlameReaderWriter { @@ -13,6 +13,7 @@ public interface IBlameReaderWriter /// /// List of tests in sequence /// The path of file + /// File Path string WriteTestSequence(List testSequence, string filePath); /// diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj index edf65287d3..b68ec21728 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj @@ -9,7 +9,9 @@ Microsoft.TestPlatform.Extensions.BlameDataCollector - net46;netstandard1.5 + netstandard1.5;net46 + true + true diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/XmlReaderWriter.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/XmlReaderWriter.cs index ecedc66efa..a29f8a4872 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/XmlReaderWriter.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/XmlReaderWriter.cs @@ -32,6 +32,7 @@ internal XmlReaderWriter() } /// + /// Initializes a new instance of the class. /// Protected for testing purposes /// /// @@ -53,6 +54,7 @@ protected XmlReaderWriter(IFileHelper fileHelper) /// /// The file Path. /// + /// File path public string WriteTestSequence(List testSequence, string filePath) { ValidateArg.NotNull(testSequence, nameof(testSequence)); @@ -74,6 +76,7 @@ public string WriteTestSequence(List testSequence, string filePath) blameTestRoot.AppendChild(testElement); } + xmlDocument.AppendChild(blameTestRoot); using (var stream = this.fileHelper.GetStream(filePath, FileMode.Create)) { @@ -88,7 +91,7 @@ public string WriteTestSequence(List testSequence, string filePath) /// /// The path of test sequence file /// Test Case List - public List ReadTestSequence(string filePath) + public List ReadTestSequence(string filePath) { ValidateArg.NotNull(filePath, nameof(filePath)); @@ -100,12 +103,13 @@ public List ReadTestSequence(string filePath) var testCaseList = new List(); try { - // Reading test sequence + // Reading test sequence var xmlDocument = new XmlDocument(); using (var stream = this.fileHelper.GetStream(filePath, FileMode.Open)) { xmlDocument.Load(stream); } + var root = xmlDocument.LastChild; foreach (XmlNode node in root) { @@ -122,6 +126,7 @@ public List ReadTestSequence(string filePath) { EqtTrace.Warning("XmlReaderWriter : Exception ", xmlException); } + return testCaseList; } } diff --git a/src/package/sign/sign.proj b/src/package/sign/sign.proj index 097f03eb03..a5932ae87c 100644 --- a/src/package/sign/sign.proj +++ b/src/package/sign/sign.proj @@ -56,6 +56,7 @@ + @@ -95,6 +96,7 @@ + diff --git a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs index 5b8b11fdb8..d26296785f 100644 --- a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs +++ b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs @@ -11,6 +11,11 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors using Microsoft.VisualStudio.TestPlatform.Common.Logging; using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + using Microsoft.VisualStudio.TestPlatform.Common.Utilities; + using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities; + using System.Xml; internal class EnableBlameArgumentProcessor : IArgumentProcessor { @@ -75,7 +80,7 @@ internal class EnableBlameArgumentProcessorCapabilities : BaseArgumentProcessorC public override bool IsAction => false; - public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.Diag; + public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.Logging; public override string HelpContentResourceName => CommandLineResources.EnableBlameUsage; @@ -126,6 +131,55 @@ public void Initialize(string argument) // Add Blame Data Collector CollectArgumentExecutor.AddDataCollectorToRunSettings(BlameFriendlyName, this.runSettingsManager); + + // Get results directory from RunSettingsManager + var runSettings = this.runSettingsManager.ActiveRunSettings; + string resultsDirectory = null; + if (runSettings != null) + { + try + { + RunConfiguration runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runSettings.SettingsXml); + resultsDirectory = RunSettingsUtilities.GetTestResultsDirectory(runConfiguration); + } + catch (SettingsException se) + { + if (EqtTrace.IsErrorEnabled) + { + EqtTrace.Error("EnableBlameArgumentProcessor: Unable to get the test results directory: Error {0}", se); + } + } + } + + // Add configuration element + var settings = runSettings?.SettingsXml; + if (settings == null) + { + runSettingsManager.AddDefaultRunSettings(); + settings = runSettings?.SettingsXml; + } + + var dataCollectionRunSettings = XmlRunSettingsUtilities.GetDataCollectionRunSettings(settings); + if (dataCollectionRunSettings == null) + { + dataCollectionRunSettings = new DataCollectionRunSettings(); + } + + var XmlDocument = new XmlDocument(); + var outernode = XmlDocument.CreateElement("Configuration"); + var node = XmlDocument.CreateElement("ResultsDirectory"); + outernode.AppendChild(node); + node.InnerText = resultsDirectory; + + foreach(var item in dataCollectionRunSettings.DataCollectorSettingsList) + { + if( item.FriendlyName.Equals(BlameFriendlyName)) + { + item.Configuration = outernode; + } + } + + runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.DataCollectionRunSettingsName, dataCollectionRunSettings.ToXml().InnerXml); } /// diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/BlameDataCollectorTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/BlameDataCollectorTests.cs new file mode 100644 index 0000000000..1a30b0bee2 --- /dev/null +++ b/test/Microsoft.TestPlatform.AcceptanceTests/BlameDataCollectorTests.cs @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Diagnostics; +using System.IO; +using System.Xml; + +namespace Microsoft.TestPlatform.AcceptanceTests +{ + [TestClass] + public class BlameDataCollectorTests : AcceptanceTestBase + { + private readonly string resultsDir; + + public BlameDataCollectorTests() + { + this.resultsDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + } + + [TestCleanup] + public void Cleanup() + { + if (Directory.Exists(this.resultsDir)) + { + Directory.Delete(this.resultsDir, true); + } + } + + [CustomDataTestMethod] + [NET46TargetFramework] + [NETCORETargetFramework] + public void BlameDataCollectorShouldGiveCorrectTestCaseName(string runnerFramework, string targetFramework, string targetRuntime) + { + + SetTestEnvironment(this.testEnvironment, runnerFramework, targetFramework, targetRuntime); + var assemblyPaths = this.BuildMultipleAssemblyPath("BlameUnitTestProject.dll").Trim('\"'); + var arguments = PrepareArguments(assemblyPaths, this.GetTestAdapterPath(), string.Empty, this.FrameworkArgValue); + arguments = string.Concat(arguments, $" /Blame"); + arguments = string.Concat(arguments, $" /ResultsDirectory:{resultsDir}"); + this.InvokeVsTest(arguments); + + this.VaildateOutput(); + } + + private void VaildateOutput() + { + bool isAttachmentReceived = false; + bool isValid = false; + this.StdErrorContains("BlameUnitTestProject.UnitTest1.TestMethod2"); + this.StdOutputContains("Sequence.xml"); + var resultFiles = Directory.GetFiles(this.resultsDir, "*", SearchOption.AllDirectories); + + foreach(var file in resultFiles) + { + if(file.Contains("Sequence.xml")) + { + isAttachmentReceived = true; + isValid = IsValidXml(file); + break; + } + } + Assert.IsTrue(isAttachmentReceived); + Assert.IsTrue(isValid); + + } + + private bool IsValidXml(string xmlFilePath) + { + var file = File.OpenRead(xmlFilePath); + var reader = XmlReader.Create(file); + try + { + while (reader.Read()) + { + } + file.Dispose(); + return true; + } + catch (XmlException) + { + file.Dispose(); + return false; + } + } + } +} diff --git a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs index 064f739580..b1d75c5cee 100644 --- a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameCollectorTests.cs @@ -29,6 +29,7 @@ public class BlameCollectorTests private Mock mockDataCollectionSink; private Mock mockBlameReaderWriter; private XmlElement configurationElement; + private string filepath; /// /// Initializes a new instance of the class. @@ -47,6 +48,10 @@ public BlameCollectorTests() this.dataCollectionContext = new DataCollectionContext(testcase); this.configurationElement = null; this.context = new DataCollectionEnvironmentContext(this.dataCollectionContext); + + this.filepath = Path.Combine(Path.GetTempPath(), "Test"); + FileStream stream = File.Create(this.filepath); + stream.Dispose(); } /// @@ -70,8 +75,8 @@ public void InitializeShouldThrowExceptionIfDataCollectionLoggerIsNull() /// The trigger session ended handler should write to file if test start count is greater. /// [TestMethod] - public void TriggerSessionEndedHandlerShouldWriteToFileIfTestStartCountIsGreater() - { + public void TriggerSessionEndedHandlerShouldWriteToFileIfTestHostCrash() + { // Initializing Blame Data Collector this.blameDataCollector.Initialize( this.configurationElement, @@ -80,29 +85,24 @@ public void TriggerSessionEndedHandlerShouldWriteToFileIfTestStartCountIsGreater this.mockLogger.Object, this.context); - var filepath = Path.Combine(AppContext.BaseDirectory, "Test"); TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); - using (var fs = File.Create(filepath)) - { - } // Setup and Raise TestCaseStart and Session End Event this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny>(), It.IsAny())) - .Returns(filepath); + .Returns(this.filepath); this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase)); this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext)); // Verify WriteTestSequence Call this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), It.IsAny()), Times.Once); - File.Delete(filepath); } /// /// The trigger session ended handler should not write to file if test start count is same as test end count. /// [TestMethod] - public void TriggerSessionEndedHandlerShouldNotWriteToFileIfTestStartCountIsSameAsTestEndCount() + public void TriggerSessionEndedHandlerShouldNotWriteToFileIfNoTestHostCrash() { // Initializing Blame Data Collector this.blameDataCollector.Initialize( @@ -112,16 +112,22 @@ public void TriggerSessionEndedHandlerShouldNotWriteToFileIfTestStartCountIsSame this.mockLogger.Object, this.context); - var filepath = Path.Combine(AppContext.BaseDirectory, "TestSequence.xml"); TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll"); // Setup and Raise TestCaseStart and Session End Event + this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny>(), It.IsAny())).Returns(this.filepath); this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase)); this.mockDataColectionEvents.Raise(x => x.TestCaseEnd += null, new TestCaseEndEventArgs(testcase, TestOutcome.Passed)); this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext)); // Verify WriteTestSequence Call - this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), filepath), Times.Never); + this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny>(), this.filepath), Times.Never); + } + + [TestCleanup] + public void CleanUp() + { + File.Delete(this.filepath); } /// diff --git a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameLoggerTests.cs b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameLoggerTests.cs index e05232406f..9ad7ab37b7 100644 --- a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameLoggerTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/BlameLoggerTests.cs @@ -112,7 +112,7 @@ public void TestRunCompleteHandlerShouldGetFaultyTestRunIfTestRunAborted() /// [TestMethod] public void TestRunCompleteHandlerShouldNotReadFileIfTestRunNotAborted() - { + { // Initialize Blame Logger this.blameLogger.Initialize(this.events.Object, null); @@ -154,9 +154,10 @@ public void TestRunCompleteHandlerShouldReturnIfUriAttachmentIsNull() internal class TestableTestLoggerManager : TestLoggerManager { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - internal TestableTestLoggerManager() : base(TestSessionMessageLogger.Instance, new InternalTestLoggerEvents(TestSessionMessageLogger.Instance)) + internal TestableTestLoggerManager() + : base(TestSessionMessageLogger.Instance, new InternalTestLoggerEvents(TestSessionMessageLogger.Instance)) { } } @@ -167,7 +168,7 @@ internal class TestableTestLoggerManager : TestLoggerManager internal class TestableBlameLogger : BlameLogger { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The output. diff --git a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj index bb5e50e93c..3be756b688 100644 --- a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj @@ -11,6 +11,8 @@ netcoreapp1.0;net46 Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests + true + true diff --git a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs index b84f6b0e66..1104be02ae 100644 --- a/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/XmlReaderWriterTests.cs @@ -23,7 +23,7 @@ public class XmlReaderWriterTests private TestableXmlReaderWriter xmlReaderWriter; private Mock mockFileHelper; private Mock mockStream; - List testCaseList; + private List testCaseList; private TestCase testcase; /// @@ -115,7 +115,6 @@ public void ReadTestSequenceShouldReadFileStream() // Verify Call to stream read this.mockStream.Verify(x => x.Read(It.IsAny(), It.IsAny(), It.IsAny())); - } /// diff --git a/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj b/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj new file mode 100644 index 0000000000..04f46d0bed --- /dev/null +++ b/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj @@ -0,0 +1,31 @@ + + + + + + + + + BlameUnitTestProject + netcoreapp1.0;netcoreapp1.1;netcoreapp2.0;net46 + + + + + + + + + + + + + diff --git a/test/TestAssets/BlameUnitTestProject/UnitTest1.cs b/test/TestAssets/BlameUnitTestProject/UnitTest1.cs new file mode 100644 index 0000000000..22f89e4efd --- /dev/null +++ b/test/TestAssets/BlameUnitTestProject/UnitTest1.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace BlameUnitTestProject +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System; + using System.Threading; + + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + Thread.Sleep(5000); + } + + [TestMethod] + public void TestMethod2() + { + Thread.Sleep(5000); + Environment.Exit(1); + } + } +} diff --git a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs index 669a7b84c8..d162159b8c 100644 --- a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs @@ -16,7 +16,7 @@ public class EnableBlameArgumentProcessorTests private TestableRunSettingsProvider settingsProvider; private EnableBlameArgumentExecutor executor; private DummyTestLoggerManager testloggerManager; - private const string DefaultRunSettings = "\r\n\r\n \r\n {0}\r\n \r\n"; + private const string DefaultRunSettings = "\r\n\r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n "; public EnableBlameArgumentProcessorTests() { @@ -61,13 +61,13 @@ public void InitializeShouldCreateEntryForBlameInRunSettingsIfNotAlreadyPresent( { var runsettingsString = string.Format(DefaultRunSettings, ""); var runsettings = new RunSettings(); - runsettings.LoadSettingsXml(runsettingsString); + runsettings.LoadSettingsXml(DefaultRunSettings); this.settingsProvider.SetActiveRunSettings(runsettings); this.executor.Initialize(""); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); - Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); + 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", this.settingsProvider.ActiveRunSettings.SettingsXml); } [TestMethod] From 5663e13eeb80a8febd649179c16cbea3c7d6603a Mon Sep 17 00:00:00 2001 From: t-vanidh Date: Wed, 12 Jul 2017 22:02:05 +0530 Subject: [PATCH 7/9] Blame Processor priority changed in test --- .../Processors/EnableBlameArgumentProcessorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs index d162159b8c..2a11638683 100644 --- a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs @@ -47,7 +47,7 @@ public void CapabilitiesShouldReturnAppropriateProperties() Assert.AreEqual("/Blame", capabilities.CommandName); Assert.AreEqual(false, capabilities.IsAction); - Assert.AreEqual(ArgumentProcessorPriority.Diag, capabilities.Priority); + Assert.AreEqual(ArgumentProcessorPriority.Logging, capabilities.Priority); Assert.AreEqual(HelpContentPriority.EnableDiagArgumentProcessorHelpPriority, capabilities.HelpPriority); Assert.AreEqual(CommandLineResources.EnableBlameUsage, capabilities.HelpContentResourceName); From 35e5cf8c52fe3ddc872d3713e9d852f0f02b9691 Mon Sep 17 00:00:00 2001 From: t-vanidh Date: Thu, 13 Jul 2017 11:05:55 +0530 Subject: [PATCH 8/9] BlameUnitTestProject updated --- .../BlameDataCollectorTests.cs | 12 +++++------- .../BlameUnitTestProject/BlameUnitTestProject.csproj | 11 ----------- test/TestAssets/BlameUnitTestProject/UnitTest1.cs | 2 -- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/BlameDataCollectorTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/BlameDataCollectorTests.cs index 1a30b0bee2..16f9dd4297 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/BlameDataCollectorTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/BlameDataCollectorTests.cs @@ -1,14 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Diagnostics; -using System.IO; -using System.Xml; - namespace Microsoft.TestPlatform.AcceptanceTests { + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System; + using System.IO; + using System.Xml; + [TestClass] public class BlameDataCollectorTests : AcceptanceTestBase { @@ -63,7 +62,6 @@ private void VaildateOutput() } Assert.IsTrue(isAttachmentReceived); Assert.IsTrue(isValid); - } private bool IsValidXml(string xmlFilePath) diff --git a/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj b/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj index 04f46d0bed..6d5d9394c5 100644 --- a/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj +++ b/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj @@ -10,20 +10,9 @@ netcoreapp1.0;netcoreapp1.1;netcoreapp2.0;net46 - - - diff --git a/test/TestAssets/BlameUnitTestProject/UnitTest1.cs b/test/TestAssets/BlameUnitTestProject/UnitTest1.cs index 22f89e4efd..83e741270f 100644 --- a/test/TestAssets/BlameUnitTestProject/UnitTest1.cs +++ b/test/TestAssets/BlameUnitTestProject/UnitTest1.cs @@ -13,13 +13,11 @@ public class UnitTest1 [TestMethod] public void TestMethod1() { - Thread.Sleep(5000); } [TestMethod] public void TestMethod2() { - Thread.Sleep(5000); Environment.Exit(1); } } From 8599465c196eb08b9fe6e34aace6cb0af63cb9c5 Mon Sep 17 00:00:00 2001 From: t-vanidh Date: Thu, 13 Jul 2017 11:55:00 +0530 Subject: [PATCH 9/9] SDK Previous version updated to 15.3.0-preview-20170628-02 --- scripts/build/TestPlatform.Dependencies.props | 2 +- .../BlameUnitTestProject.csproj | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/scripts/build/TestPlatform.Dependencies.props b/scripts/build/TestPlatform.Dependencies.props index 045b214fc9..0f8c68afa6 100644 --- a/scripts/build/TestPlatform.Dependencies.props +++ b/scripts/build/TestPlatform.Dependencies.props @@ -4,7 +4,7 @@ 15.0.26201 - 15.0.0 + 15.3.0-preview-20170628-02 1.1.18 1.1.18 diff --git a/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj b/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj index 6d5d9394c5..8ff8ab5f79 100644 --- a/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj +++ b/test/TestAssets/BlameUnitTestProject/BlameUnitTestProject.csproj @@ -10,9 +10,20 @@ netcoreapp1.0;netcoreapp1.1;netcoreapp2.0;net46 - + + + + + $(MSTestFrameworkVersion) + + + $(MSTestAdapterVersion) + + + $(NETTestSdkPreviousVersion) +