From 140434f7109d357d0158ade9e5164a4861513965 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 1 Dec 2020 03:59:41 +0100 Subject: [PATCH 01/46] Update dependencies from https://github.com/dotnet/arcade build 20201130.3 (#2659) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.SwaggerGenerator.MSBuild From Version 1.0.0-beta.20570.10 -> To Version 1.0.0-beta.20580.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 6 +++--- global.json | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0ac3fbcb4b..c0db89e933 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,25 +3,25 @@ - + https://github.com/dotnet/arcade - 1ceac96c54fcf33eb745649c4e7b8d7507a9b730 + 7ee8c2b620e66b3762d7a5a688dee8238770c86a - + https://github.com/dotnet/arcade - 1ceac96c54fcf33eb745649c4e7b8d7507a9b730 + 7ee8c2b620e66b3762d7a5a688dee8238770c86a - + https://github.com/dotnet/arcade - 1ceac96c54fcf33eb745649c4e7b8d7507a9b730 + 7ee8c2b620e66b3762d7a5a688dee8238770c86a - + https://github.com/dotnet/arcade - 1ceac96c54fcf33eb745649c4e7b8d7507a9b730 + 7ee8c2b620e66b3762d7a5a688dee8238770c86a - + https://github.com/dotnet/arcade - 1ceac96c54fcf33eb745649c4e7b8d7507a9b730 + 7ee8c2b620e66b3762d7a5a688dee8238770c86a https://github.com/dotnet/arcade-services diff --git a/eng/Versions.props b/eng/Versions.props index e708d770fc..1a2aa5a737 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,8 +60,8 @@ 2.4.1 2.0.3 2.4.1 - 2.2.0-beta.20570.10 - 1.0.0-beta.20570.10 + 2.2.0-beta.20580.3 + 1.0.0-beta.20580.3 1.22.0 1.1.2 2.0.0 @@ -73,7 +73,7 @@ 1.7.0 1.1.0-beta.19556.4 1.0.0-beta2-19554-01 - 1.0.0-beta.20570.10 + 1.0.0-beta.20580.3 1.0.0-beta.20055.1 - - + + - + @@ -275,16 +275,17 @@ - - - - - + + + + + + - - + + From 01b4991e5dad92197c09e743226b94157f2200ff Mon Sep 17 00:00:00 2001 From: Adam Ralph Date: Fri, 4 Dec 2020 02:38:01 +0100 Subject: [PATCH 03/46] Fixed "issue" pluralization in write-release-notes.ps1 (#2665) * Fixed "issue" pluralization in write-release-notes.ps1 Co-authored-by: Medeni Baykal <433724+Haplois@users.noreply.github.com> --- scripts/write-release-notes.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/write-release-notes.ps1 b/scripts/write-release-notes.ps1 index b356f88af9..bc103e7b77 100644 --- a/scripts/write-release-notes.ps1 +++ b/scripts/write-release-notes.ps1 @@ -103,7 +103,7 @@ See the release notes [here](https://github.com/microsoft/vstest-docs/blob/maste ## $v -### Issue Fixed +### $(if ($issues.Length -eq 1) { 'Issue' } else { 'Issues' }) Fixed $($issues -join "`n") See full log [here]($repoUrl/compare/$start...$tag) From 02d1799fcb0060a96edb5cdc42dd09bc02fbe074 Mon Sep 17 00:00:00 2001 From: Vritant Bhardwaj Date: Fri, 4 Dec 2020 17:12:06 -0800 Subject: [PATCH 04/46] Bumping Fakes TestRunnerHarness version (#2661) --- NuGet.config | 2 +- scripts/build/TestPlatform.Dependencies.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.config b/NuGet.config index f07d7285be..95f0f7b047 100644 --- a/NuGet.config +++ b/NuGet.config @@ -16,7 +16,7 @@ - + diff --git a/scripts/build/TestPlatform.Dependencies.props b/scripts/build/TestPlatform.Dependencies.props index 0f20954db6..986afff988 100644 --- a/scripts/build/TestPlatform.Dependencies.props +++ b/scripts/build/TestPlatform.Dependencies.props @@ -33,7 +33,7 @@ 4.7.63 16.9.0-preview-4267359 16.9.0-beta.20603.1 - 16.8.0-beta.20420.2 + 16.9.0-beta.20602.2 16.0.461 $(MicrosoftBuildPackageVersion) From 16dff22d1a43280b47556bb9080ccfdc600591e6 Mon Sep 17 00:00:00 2001 From: jflepp Date: Wed, 9 Dec 2020 11:03:30 +0100 Subject: [PATCH 05/46] Implement Workitem support in TRX logger (#2666) * Implemented Workitem support in TRX logger * Renamed Workitem to WorkItem Co-authored-by: Flepp Jann --- .../Interfaces/ITestElement.cs | 1 + .../ObjectModel/TestElement.cs | 18 ++ .../ObjectModel/WorkItems.cs | 243 ++++++++++++++++++ .../Utility/Converter.cs | 7 + .../TrxLoggerTests.cs | 22 +- .../Utility/ConverterTests.cs | 16 ++ 6 files changed, 304 insertions(+), 3 deletions(-) create mode 100644 src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/WorkItems.cs diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestElement.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestElement.cs index 92d7db22f4..39121ae3e0 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestElement.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestElement.cs @@ -16,6 +16,7 @@ internal interface ITestElement TestExecId ParentExecutionId { get; set; } TestListCategoryId CategoryId { get; set; } TestCategoryItemCollection TestCategories { get; } + WorkItemCollection WorkItems { get; set; } TestType TestType { get; } } } diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElement.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElement.cs index 9562822962..c35fa8b3a1 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElement.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElement.cs @@ -30,6 +30,7 @@ internal abstract class TestElement : ITestElement, IXmlTestStore protected TestExecId executionId; protected TestExecId parentExecutionId; protected TestCategoryItemCollection testCategories; + protected WorkItemCollection workItems; protected TestListCategoryId catId; public TestElement(Guid id, string name, string adapter) @@ -161,6 +162,20 @@ public TestCategoryItemCollection TestCategories } } + /// + /// Gets or sets the work items. + /// + public WorkItemCollection WorkItems + { + get { return this.workItems; } + + set + { + EqtAssert.ParameterNotNull(value, "value"); + this.workItems = value; + } + } + /// /// Gets the adapter name. /// @@ -230,6 +245,8 @@ public virtual void Save(System.Xml.XmlElement element, XmlTestStoreParameters p if (this.parentExecutionId != null) h.SaveGuid(element, "Execution/@parentId", this.parentExecutionId.Id); + h.SaveObject(this.workItems, element, "Workitems", parameters); + XmlTestStoreParameters testIdParameters = XmlTestStoreParameters.GetParameters(); testIdParameters[TestId.IdLocationKey] = "@id"; h.SaveObject(this.id, element, testIdParameters); @@ -245,6 +262,7 @@ private void Initialize() this.executionId = TestExecId.Empty; this.parentExecutionId = TestExecId.Empty; this.testCategories = new TestCategoryItemCollection(); + this.workItems = new WorkItemCollection(); this.isRunnable = true; this.catId = TestListCategoryId.Uncategorized; } diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/WorkItems.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/WorkItems.cs new file mode 100644 index 0000000000..c21769539d --- /dev/null +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/WorkItems.cs @@ -0,0 +1,243 @@ +// 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.Extensions.TrxLogger.ObjectModel +{ + using System; + using System.Globalization; + using System.Text; + using System.Xml; + using Microsoft.TestPlatform.Extensions.TrxLogger.Utility; + using Microsoft.TestPlatform.Extensions.TrxLogger.XML; + + #region WorkItem + /// + /// Stores an int which represents a workitem + /// + internal sealed class WorkItem : IXmlTestStore + { + #region Fields + [StoreXmlField(Location = ".")] + private int id = 0; + + #endregion + + #region Constructors + /// + /// Create a new item with the workitem set + /// + /// The workitem. + public WorkItem(int workitemId) + { + this.id = workitemId; + } + + #endregion + + #region Properties/Methods + /// + /// Gets the id for this WorkItem + /// + public int Id + { + get + { + return this.id; + } + } + + #endregion + + #region Methods - overrides + /// + /// Compare the values of the items + /// + /// Value being compared to. + /// True if the values are the same and false otherwise. + public override bool Equals(object other) + { + WorkItem otherItem = other as WorkItem; + if (otherItem == null) + { + return false; + } + return this.id == otherItem.id; + } + + /// + /// Convert the workitem to a hashcode + /// + /// Hashcode of the workitem. + public override int GetHashCode() + { + return this.id.GetHashCode(); + } + + /// + /// Convert the workitem to a string + /// + /// The workitem. + public override string ToString() + { + return this.id.ToString(CultureInfo.InvariantCulture); + } + #endregion + + #region IXmlTestStore Members + + /// + /// Saves the class under the XmlElement. + /// + /// XmlElement element + /// XmlTestStoreParameters parameters + public void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters) + { + new XmlPersistence().SaveSingleFields(element, this, parameters); + } + + #endregion + } + #endregion + + #region WorkItemCollection + /// + /// A collection of ints represent the workitems + /// + internal sealed class WorkItemCollection : EqtBaseCollection + { + #region Constructors + /// + /// Creates an empty WorkItemCollection. + /// + public WorkItemCollection() + { + } + + /// + /// Create a new WorkItemCollection based on the int array. + /// + /// Add these items to the collection. + public WorkItemCollection(int[] items) + { + EqtAssert.ParameterNotNull(items, "items"); + foreach (int i in items) + { + this.Add(new WorkItem(i)); + } + } + + #endregion + + #region Methods + /// + /// Adds the workitem. + /// + /// WorkItem to be added. + public void Add(int item) + { + this.Add(new WorkItem(item)); + } + + /// + /// Adds the workitem. + /// + /// WorkItem to be added. + public override void Add(WorkItem item) + { + EqtAssert.ParameterNotNull(item, "item"); + base.Add(item); + } + + /// + /// Convert the WorkItemCollection to a string. + /// each item is separated by a comma (,) + /// + /// + public override string ToString() + { + StringBuilder returnString = new StringBuilder(); + if (this.Count > 0) + { + returnString.Append(","); + foreach (WorkItem item in this) + { + returnString.Append(item); + returnString.Append(","); + } + } + + return returnString.ToString(); + } + + /// + /// Convert the WorkItemCollection to an array of ints. + /// + /// Array of ints containing the workitems. + public int[] ToArray() + { + int[] result = new int[this.Count]; + + int i = 0; + foreach (WorkItem item in this) + { + result[i++] = item.Id; + } + + return result; + } + + /// + /// Compare the collection items + /// + /// other collection + /// true if the collections contain the same items + public override bool Equals(object obj) + { + WorkItemCollection other = obj as WorkItemCollection; + bool result = false; + + if (other == null) + { + result = false; + } + else if (object.ReferenceEquals(this, other)) + { + result = true; + } + else if (this.Count != other.Count) + { + result = false; + } + else + { + foreach (WorkItem item in this) + { + if (!other.Contains(item)) + { + result = false; + break; + } + } + } + + return result; + } + + /// + /// Return the hash code of this collection + /// + /// The hashcode. + public override int GetHashCode() + { + return base.GetHashCode(); + } + + public override void Save(XmlElement element, XmlTestStoreParameters parameters) + { + XmlPersistence xmlPersistence = new XmlPersistence(); + xmlPersistence.SaveHashtable(this.container, element, ".", ".", null, "Workitem", parameters); + } + #endregion + } + #endregion +} diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs index 3ca84b4694..eeb441f0d4 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs @@ -67,6 +67,13 @@ public ITestElement ToTestElement( testElement.TestCategories.Add(testCategory); } + var workItems = GetCustomPropertyValueFromTestCase(rockSteadyTestCase, "WorkItemIds") + .Select(workItem => int.Parse(workItem)); + foreach (int workItem in workItems) + { + testElement.WorkItems.Add(workItem); + } + return testElement; } diff --git a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs index c55c000053..67dd775c4a 100644 --- a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs @@ -736,13 +736,11 @@ public void CustomTrxFileNameShouldConstructFromLogFileParameter() Assert.AreEqual(Path.Combine(TrxLoggerTests.DefaultTestRunDirectory, TrxLoggerTests.DefaultLogFileNameParameterValue), this.testableTrxLogger.trxFile, "Wrong Trx file name"); } - - /// /// Unit test for reading TestCategories from the TestCase which is part of test result. /// [TestMethod] - public void GetCustomPropertyValueFromTestCaseShouldReadCategoyrAttributesFromTestCase() + public void GetCustomPropertyValueFromTestCaseShouldReadCategoryAttributesFromTestCase() { ObjectModel.TestCase testCase1 = CreateTestCase("TestCase1"); TestProperty testProperty = TestProperty.Register("MSTestDiscoverer.TestCategory", "String array property", string.Empty, string.Empty, typeof(string[]), null, TestPropertyAttributes.Hidden, typeof(TestObject)); @@ -759,6 +757,24 @@ public void GetCustomPropertyValueFromTestCaseShouldReadCategoyrAttributesFromTe CollectionAssert.AreEqual(listCategoriesExpected, listCategoriesActual); } + [TestMethod] + public void GetCustomPropertyValueFromTestCaseShouldReadWorkItemAttributesFromTestCase() + { + ObjectModel.TestCase testCase1 = CreateTestCase("TestCase1"); + TestProperty testProperty = TestProperty.Register("WorkItemIds", "String array property", string.Empty, string.Empty, typeof(string[]), null, TestPropertyAttributes.Hidden, typeof(TestObject)); + + testCase1.SetPropertyValue(testProperty, new[] { "99999", "0" }); + + var converter = new Converter(new Mock().Object, new TrxFileHelper()); + List listWorkItemsActual = converter.GetCustomPropertyValueFromTestCase(testCase1, "WorkItemIds"); + + List listWorkItemsExpected = new List(); + listWorkItemsExpected.Add("99999"); + listWorkItemsExpected.Add("0"); + + CollectionAssert.AreEqual(listWorkItemsExpected, listWorkItemsActual); + } + [TestMethod] public void CRLFCharactersShouldGetRetainedInTrx() { diff --git a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Utility/ConverterTests.cs b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Utility/ConverterTests.cs index 6311ba1715..e4c2323f83 100644 --- a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Utility/ConverterTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Utility/ConverterTests.cs @@ -98,6 +98,22 @@ public void ToTestElementShouldAssignTestCategoryOfUnitTestElement() CollectionAssert.AreEqual(expected, unitTestElement.TestCategories.ToArray().OrderByDescending(x => x.ToString()).ToArray()); } + [TestMethod] + public void ToTestElementShouldAssignWorkitemOfUnitTestElement() + { + TestPlatformObjectModel.TestCase testCase = CreateTestCase("TestCase1"); + TestPlatformObjectModel.TestResult result = new TestPlatformObjectModel.TestResult(testCase); + TestProperty testProperty = TestProperty.Register("WorkItemIds", "String array property", string.Empty, string.Empty, typeof(string[]), null, TestPropertyAttributes.Hidden, typeof(TestObject)); + + testCase.SetPropertyValue(testProperty, new[] { "3", "99999", "0" }); + + var unitTestElement = this.converter.ToTestElement(testCase.Id, Guid.Empty, Guid.Empty, testCase.DisplayName, TrxLoggerConstants.UnitTestType, testCase); + + int[] expected = new[] { 0, 3, 99999 }; + + CollectionAssert.AreEquivalent(expected, unitTestElement.WorkItems.ToArray()); + } + /// /// Unit test for regression when there's no test categories. /// From 269dcaaed40031b28c9091f45dc4a22cd8ac95aa Mon Sep 17 00:00:00 2001 From: Jakub Chocholowicz <59966772+jakubch1@users.noreply.github.com> Date: Thu, 10 Dec 2020 14:14:15 +0100 Subject: [PATCH 06/46] Do not merge logs from code coverage (#2671) --- .../CodeCoverageDataAttachmentsHandler.cs | 66 ++++++++++++++----- ...CodeCoverageDataAttachmentsHandlerTests.cs | 46 +++++++++++-- 2 files changed, 91 insertions(+), 21 deletions(-) diff --git a/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs b/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs index 3c2ceeff0f..9e9d559190 100644 --- a/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs +++ b/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs @@ -8,7 +8,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Utilities using System.Collections.ObjectModel; using System.IO; using System.Linq; - using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -16,7 +15,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Utilities using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; - using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; public class CodeCoverageDataAttachmentsHandler : IDataCollectorAttachmentProcessor { @@ -37,17 +35,41 @@ public async Task> ProcessAttachmentSetsAsync(ICollec { if (attachments != null && attachments.Any()) { - var codeCoverageFiles = attachments.Select(coverageAttachment => coverageAttachment.Attachments[0].Uri.LocalPath).ToArray(); - var outputFile = await this.MergeCodeCoverageFilesAsync(codeCoverageFiles, progressReporter, cancellationToken).ConfigureAwait(false); - var attachmentSet = new AttachmentSet(CodeCoverageDataCollectorUri, CoverageFriendlyName); + var coverageReportFilePaths = new List(); + var coverageOtherFilePaths = new List(); - if (!string.IsNullOrEmpty(outputFile)) + foreach (var attachmentSet in attachments) { - attachmentSet.Attachments.Add(new UriDataAttachment(new Uri(outputFile), CoverageFriendlyName)); - return new Collection { attachmentSet }; + foreach (var attachment in attachmentSet.Attachments) + { + if (attachment.Uri.LocalPath.EndsWith(CoverageFileExtension, StringComparison.OrdinalIgnoreCase)) + { + coverageReportFilePaths.Add(attachment.Uri.LocalPath); + } + else + { + coverageOtherFilePaths.Add(attachment.Uri.LocalPath); + } + } + } + + if(coverageReportFilePaths.Count > 1) + { + var mergedCoverageReportFilePath = await this.MergeCodeCoverageFilesAsync(coverageReportFilePaths, progressReporter, cancellationToken).ConfigureAwait(false); + if (!string.IsNullOrEmpty(mergedCoverageReportFilePath)) + { + var resultAttachmentSet = new AttachmentSet(CodeCoverageDataCollectorUri, CoverageFriendlyName); + resultAttachmentSet.Attachments.Add(new UriDataAttachment(new Uri(mergedCoverageReportFilePath), CoverageFriendlyName)); + + foreach (var coverageOtherFilePath in coverageOtherFilePaths) + { + resultAttachmentSet.Attachments.Add(new UriDataAttachment(new Uri(coverageOtherFilePath), string.Empty)); + } + + return new Collection { resultAttachmentSet }; + } } - // In case merging fails(esp in dotnet core we cannot merge), so return filtered list of Code Coverage Attachments return attachments; } @@ -56,11 +78,6 @@ public async Task> ProcessAttachmentSetsAsync(ICollec private async Task MergeCodeCoverageFilesAsync(IList files, IProgress progressReporter, CancellationToken cancellationToken) { - if (files.Count == 1) - { - return files[0]; - } - try { // Warning: Don't remove this method call. @@ -68,8 +85,9 @@ private async Task MergeCodeCoverageFilesAsync(IList files, IPro // We took a dependency on Coverage.CoreLib.Net. In the unlikely case it cannot be // resolved, this method call will throw an exception that will be caught and // absorbed here. - await this.MergeCodeCoverageFilesAsync(files, cancellationToken).ConfigureAwait(false); + var result = await this.MergeCodeCoverageFilesAsync(files, cancellationToken).ConfigureAwait(false); progressReporter?.Report(100); + return result; } catch (OperationCanceledException) { @@ -83,10 +101,10 @@ private async Task MergeCodeCoverageFilesAsync(IList files, IPro ex.ToString()); } - return files[0]; + return null; } - private async Task MergeCodeCoverageFilesAsync(IList files, CancellationToken cancellationToken) + private async Task MergeCodeCoverageFilesAsync(IList files, CancellationToken cancellationToken) { var coverageUtility = new CoverageFileUtility(); @@ -95,6 +113,20 @@ private async Task MergeCodeCoverageFilesAsync(IList files, Cancellation cancellationToken).ConfigureAwait(false); coverageUtility.WriteCoverageFile(files[0], coverageData); + + foreach(var file in files.Skip(1)) + { + try + { + File.Delete(file); + } + catch (Exception ex) + { + EqtTrace.Error($"CodeCoverageDataCollectorAttachmentsHandler: Failed to remove {file}. Error: {ex}"); + } + } + + return files[0]; } } } diff --git a/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs b/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs index b87bdc8dae..f1373f5f6e 100644 --- a/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs +++ b/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs @@ -45,8 +45,8 @@ public async Task HandleDataCollectionAttachmentSetsShouldReturnEmptySetWhenNoAt [TestMethod] public async Task HandleDataCollectionAttachmentSetsShouldReturnInputIfOnly1Attachment() { - var attachmentSet = new AttachmentSet(new Uri("//badrui//"), string.Empty); - attachmentSet.Attachments.Add(new UriDataAttachment(new Uri("C:\\temp\\aa"), "coverage")); + var attachmentSet = new AttachmentSet(new Uri("datacollector://microsoft/CodeCoverage/2.0"), string.Empty); + attachmentSet.Attachments.Add(new UriDataAttachment(new Uri("C:\\temp\\aa.coverage"), "coverage")); Collection attachment = new Collection { attachmentSet }; ICollection resultAttachmentSets = await @@ -54,15 +54,53 @@ public async Task HandleDataCollectionAttachmentSetsShouldReturnInputIfOnly1Atta Assert.IsNotNull(resultAttachmentSets); Assert.IsTrue(resultAttachmentSets.Count == 1); + Assert.IsTrue(resultAttachmentSets.First().Attachments.Count == 1); Assert.AreEqual("datacollector://microsoft/CodeCoverage/2.0", resultAttachmentSets.First().Uri.AbsoluteUri); - Assert.AreEqual("file:///C:/temp/aa", resultAttachmentSets.First().Attachments.First().Uri.AbsoluteUri); + Assert.AreEqual("file:///C:/temp/aa.coverage", resultAttachmentSets.First().Attachments.First().Uri.AbsoluteUri); + } + + [TestMethod] + public async Task HandleDataCollectionAttachmentSetsShouldReturnInputIfOnly1LogsAttachment() + { + var attachmentSet = new AttachmentSet(new Uri("datacollector://microsoft/CodeCoverage/2.0"), string.Empty); + attachmentSet.Attachments.Add(new UriDataAttachment(new Uri("C:\\temp\\aa.logs"), "coverage")); + + Collection attachment = new Collection { attachmentSet }; + ICollection resultAttachmentSets = await + coverageDataAttachmentsHandler.ProcessAttachmentSetsAsync(attachment, mockProgressReporter.Object, null, CancellationToken.None); + + Assert.IsNotNull(resultAttachmentSets); + Assert.IsTrue(resultAttachmentSets.Count == 1); + Assert.IsTrue(resultAttachmentSets.First().Attachments.Count == 1); + Assert.AreEqual("datacollector://microsoft/CodeCoverage/2.0", resultAttachmentSets.First().Uri.AbsoluteUri); + Assert.AreEqual("file:///C:/temp/aa.logs", resultAttachmentSets.First().Attachments.First().Uri.AbsoluteUri); + } + + [TestMethod] + public async Task HandleDataCollectionAttachmentSetsShouldReturnInputIfOnlySeveralLogsAttachmentAnd1Report() + { + var attachmentSet = new AttachmentSet(new Uri("datacollector://microsoft/CodeCoverage/2.0"), string.Empty); + attachmentSet.Attachments.Add(new UriDataAttachment(new Uri("C:\\temp\\aa.coverage"), "coverage")); + + var attachmentSet1 = new AttachmentSet(new Uri("datacollector://microsoft/CodeCoverage/2.0"), string.Empty); + attachmentSet1.Attachments.Add(new UriDataAttachment(new Uri("C:\\temp\\aa.logs"), "coverage")); + attachmentSet1.Attachments.Add(new UriDataAttachment(new Uri("C:\\temp\\bb.logs"), "coverage")); + + Collection attachment = new Collection { attachmentSet, attachmentSet1 }; + ICollection resultAttachmentSets = await + coverageDataAttachmentsHandler.ProcessAttachmentSetsAsync(attachment, mockProgressReporter.Object, null, CancellationToken.None); + + Assert.IsNotNull(resultAttachmentSets); + Assert.IsTrue(resultAttachmentSets.Count == 2); + Assert.IsTrue(resultAttachmentSets.First().Attachments.Count == 1); + Assert.IsTrue(resultAttachmentSets.Last().Attachments.Count == 2); } [TestMethod] public async Task HandleDataCollectionAttachmentSetsShouldThrowIfCancellationRequested() { var attachmentSet = new AttachmentSet(new Uri("//badrui//"), string.Empty); - attachmentSet.Attachments.Add(new UriDataAttachment(new Uri("C:\\temp\\aa"), "coverage")); + attachmentSet.Attachments.Add(new UriDataAttachment(new Uri("C:\\temp\\aa.coverage"), "coverage")); CancellationTokenSource cts = new CancellationTokenSource(); cts.Cancel(); From 70abd6362b63f0e3ec926b3e9482785b21e406be Mon Sep 17 00:00:00 2001 From: Codrin-Victor Poienaru Date: Fri, 11 Dec 2020 20:50:36 +0100 Subject: [PATCH 07/46] Early testhost startup performance work (#2584) --- .../DesignMode/DesignModeClient.cs | 87 +- .../DesignModeTestHostLauncherFactory.cs | 4 +- .../RequestHelper/ITestRequestManager.cs | 88 +- .../TestPlatform.cs | 207 ++-- .../TestSession/TestSessionEventsHandler.cs | 72 ++ .../IProxyTestSessionManager.cs | 38 + .../Engine/ClientProtocol/ITestEngine.cs | 73 +- .../Telemetry/TelemetryDataConstants.cs | 4 + .../JsonDataSerializer.cs | 1 + .../Messages/MessageType.cs | 20 + .../TestRequestSender.cs | 7 +- .../Interfaces/ITestPlatformEventSource.cs | 40 + .../Tracing/TestPlatformEventSource.cs | 56 + .../TestPlatformInstrumentationEvents.cs | 40 + .../Client/ProxyDiscoveryManager.cs | 82 +- .../Client/ProxyExecutionManager.cs | 264 +++-- ...ProxyExecutionManagerWithDataCollection.cs | 13 +- .../Client/ProxyOperationManager.cs | 408 +++++--- ...ProxyOperationManagerWithDataCollection.cs | 146 +++ .../EventHandlers/TestRequestHandler.cs | 7 +- .../Resources/Resources.Designer.cs | 30 +- .../Resources/Resources.resx | 9 + .../Resources/xlf/Resources.cs.xlf | 15 + .../Resources/xlf/Resources.de.xlf | 15 + .../Resources/xlf/Resources.es.xlf | 15 + .../Resources/xlf/Resources.fr.xlf | 15 + .../Resources/xlf/Resources.it.xlf | 15 + .../Resources/xlf/Resources.ja.xlf | 15 + .../Resources/xlf/Resources.ko.xlf | 15 + .../Resources/xlf/Resources.pl.xlf | 15 + .../Resources/xlf/Resources.pt-BR.xlf | 15 + .../Resources/xlf/Resources.ru.xlf | 15 + .../Resources/xlf/Resources.tr.xlf | 15 + .../Resources/xlf/Resources.xlf | 15 + .../Resources/xlf/Resources.zh-Hans.xlf | 15 + .../Resources/xlf/Resources.zh-Hant.xlf | 15 + .../TestEngine.cs | 314 ++++-- .../TestSession/ProxyTestSessionManager.cs | 218 ++++ .../TestSession/TestSessionPool.cs | 167 +++ .../Client/Interfaces/IBaseProxy.cs | 20 + .../Client/Interfaces/ITestPlatform.cs | 62 +- .../Interfaces/ITestRunEventsHandler.cs | 2 +- .../Interfaces/ITestSessionEventsHandler.cs | 30 + .../Payloads/StartTestSessionAckPayload.cs | 20 + .../Payloads/StartTestSessionPayload.cs | 45 + .../Payloads/StopTestSessionAckPayload.cs | 26 + .../Client/Payloads/TestRunRequestPayload.cs | 12 +- .../Client/StartTestSessionCriteria.cs | 34 + .../Client/TestPlatformOptions.cs | 6 +- .../Client/TestRunCriteria.cs | 492 ++++++--- .../Client/TestSessionInfo.cs | 64 ++ .../Constants.cs | 2 +- .../Hosting/DefaultTestHostManager.cs | 9 +- .../Hosting/DotnetTestHostManager.cs | 9 +- .../InferRunSettingsHelper.cs | 2 +- .../Interfaces/ITestSession.cs | 180 ++++ .../Interfaces/ITestSessionAsync.cs | 182 ++++ .../ITranslationLayerRequestSender.cs | 155 ++- .../ITranslationLayerRequestSenderAsync.cs | 121 ++- .../Interfaces/IVsTestConsoleWrapper.cs | 322 ++++-- .../Interfaces/IVsTestConsoleWrapperAsync.cs | 297 +++++- .../Resources/Resources.Designer.cs | 18 + .../Resources/Resources.resx | 6 + .../Resources/xlf/Resources.cs.xlf | 10 + .../Resources/xlf/Resources.de.xlf | 10 + .../Resources/xlf/Resources.es.xlf | 10 + .../Resources/xlf/Resources.fr.xlf | 10 + .../Resources/xlf/Resources.it.xlf | 10 + .../Resources/xlf/Resources.ja.xlf | 10 + .../Resources/xlf/Resources.ko.xlf | 10 + .../Resources/xlf/Resources.pl.xlf | 10 + .../Resources/xlf/Resources.pt-BR.xlf | 10 + .../Resources/xlf/Resources.ru.xlf | 10 + .../Resources/xlf/Resources.tr.xlf | 10 + .../Resources/xlf/Resources.xlf | 10 + .../Resources/xlf/Resources.zh-Hans.xlf | 10 + .../Resources/xlf/Resources.zh-Hant.xlf | 10 + .../TestSession.cs | 373 +++++++ .../VsTestConsoleRequestSender.cs | 959 +++++++++++++++--- .../VsTestConsoleWrapper.cs | 684 +++++++++++-- src/vstest.console/CommandLine/InferHelper.cs | 4 +- .../TestPlatformHelpers/TestRequestManager.cs | 620 +++++++---- .../DesignMode/DesignModeClientTests.cs | 4 +- .../DesignModeTestHostLauncherFactoryTests.cs | 4 +- ...ExecutionManagerWithDataCollectionTests.cs | 2 +- .../InferRunSettingsHelperTests.cs | 20 +- .../VsTestConsoleRequestSenderTests.cs | 58 +- .../VsTestConsoleWrapperAsyncTests.cs | 24 +- .../VsTestConsoleWrapperTests.cs | 21 +- .../TestRequestManagerTests.cs | 32 +- 90 files changed, 6319 insertions(+), 1347 deletions(-) create mode 100644 src/Microsoft.TestPlatform.Client/TestSession/TestSessionEventsHandler.cs create mode 100644 src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyTestSessionManager.cs create mode 100644 src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManagerWithDataCollection.cs create mode 100644 src/Microsoft.TestPlatform.CrossPlatEngine/TestSession/ProxyTestSessionManager.cs create mode 100644 src/Microsoft.TestPlatform.CrossPlatEngine/TestSession/TestSessionPool.cs create mode 100644 src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IBaseProxy.cs create mode 100644 src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestSessionEventsHandler.cs create mode 100644 src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StartTestSessionAckPayload.cs create mode 100644 src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StartTestSessionPayload.cs create mode 100644 src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StopTestSessionAckPayload.cs create mode 100644 src/Microsoft.TestPlatform.ObjectModel/Client/StartTestSessionCriteria.cs create mode 100644 src/Microsoft.TestPlatform.ObjectModel/Client/TestSessionInfo.cs create mode 100644 src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITestSession.cs create mode 100644 src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITestSessionAsync.cs create mode 100644 src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/TestSession.cs diff --git a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs index 565cf31578..31812dacfa 100644 --- a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs +++ b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs @@ -9,6 +9,8 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.DesignMode using System.Net; using System.Threading; using System.Threading.Tasks; + + using Microsoft.VisualStudio.TestPlatform.Client; using Microsoft.VisualStudio.TestPlatform.Client.TestRunAttachmentsProcessing; using Microsoft.VisualStudio.TestPlatform.Client.RequestHelper; using Microsoft.VisualStudio.TestPlatform.Common.Logging; @@ -17,11 +19,14 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.DesignMode using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers; + using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces; + using CommunicationUtilitiesResources = CommunicationUtilities.Resources.Resources; /// @@ -32,7 +37,7 @@ public class DesignModeClient : IDesignModeClient private readonly ICommunicationManager communicationManager; private readonly IDataSerializer dataSerializer; - private ProtocolConfig protocolConfig = Constants.DefaultProtocolConfig; + private ProtocolConfig protocolConfig = ObjectModel.Constants.DefaultProtocolConfig; private IEnvironment platformEnvironment; private TestSessionMessageLogger testSessionMessageLogger; private object lockObject = new object(); @@ -170,6 +175,20 @@ private void ProcessRequests(ITestRequestManager testRequestManager) break; } + case MessageType.StartTestSession: + { + var testSessionPayload = this.communicationManager.DeserializePayload(message); + this.StartTestSession(testSessionPayload, testRequestManager); + break; + } + + case MessageType.StopTestSession: + { + var testSessionInfo = this.communicationManager.DeserializePayload(message); + this.StopTestSession(testSessionInfo); + break; + } + case MessageType.StartDiscovery: { var discoveryPayload = this.dataSerializer.DeserializePayload(message); @@ -183,7 +202,7 @@ private void ProcessRequests(ITestRequestManager testRequestManager) var testRunPayload = this.communicationManager.DeserializePayload( message); - this.StartTestRun(testRunPayload, testRequestManager, skipTestHostLaunch: true); + this.StartTestRun(testRunPayload, testRequestManager, shouldLaunchTesthost: true); break; } @@ -193,7 +212,7 @@ private void ProcessRequests(ITestRequestManager testRequestManager) var testRunPayload = this.communicationManager.DeserializePayload( message); - this.StartTestRun(testRunPayload, testRequestManager, skipTestHostLaunch: false); + this.StartTestRun(testRunPayload, testRequestManager, shouldLaunchTesthost: false); break; } @@ -322,7 +341,7 @@ public bool AttachDebuggerToProcess(int pid, CancellationToken cancellationToken // If an attach request is issued but there is no support for attaching on the other // side of the communication channel, we simply return and let the caller know the // request failed. - if (this.protocolConfig.Version < Constants.MinimumProtocolVersionWithDebugSupport) + if (this.protocolConfig.Version < ObjectModel.Constants.MinimumProtocolVersionWithDebugSupport) { return false; } @@ -408,7 +427,7 @@ public void TestRunMessageHandler(object sender, TestRunMessageEventArgs e) } } - private void StartTestRun(TestRunRequestPayload testRunPayload, ITestRequestManager testRequestManager, bool skipTestHostLaunch) + private void StartTestRun(TestRunRequestPayload testRunPayload, ITestRequestManager testRequestManager, bool shouldLaunchTesthost) { Task.Run( () => @@ -417,8 +436,15 @@ private void StartTestRun(TestRunRequestPayload testRunPayload, ITestRequestMana { testRequestManager.ResetOptions(); - var customLauncher = skipTestHostLaunch ? - DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(this, testRunPayload) : null; + // We must avoid re-launching the test host if the test run payload already + // contains test session info. Test session info being present is an indicative + // of an already running test host spawned by a start test session call. + var customLauncher = + shouldLaunchTesthost && testRunPayload.TestSessionInfo == null + ? DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun( + this, + testRunPayload.DebuggingEnabled) + : null; testRequestManager.RunTests(testRunPayload, customLauncher, new DesignModeTestEventsRegistrar(this), this.protocolConfig); } @@ -497,6 +523,53 @@ private void StartTestRunAttachmentsProcessing(TestRunAttachmentsProcessingPaylo }); } + private void StartTestSession(StartTestSessionPayload payload, ITestRequestManager requestManager) + { + Task.Run(() => + { + var eventsHandler = new TestSessionEventsHandler(this.communicationManager); + + try + { + var customLauncher = payload.HasCustomHostLauncher + ? DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(this, payload.IsDebuggingEnabled) + : null; + + requestManager.ResetOptions(); + requestManager.StartTestSession(payload, customLauncher, eventsHandler, this.protocolConfig); + } + catch (Exception ex) + { + EqtTrace.Error("DesignModeClient: Exception in StartTestSession: " + ex); + + eventsHandler.HandleLogMessage(TestMessageLevel.Error, ex.ToString()); + eventsHandler.HandleStartTestSessionComplete(null); + } + }); + } + + private void StopTestSession(TestSessionInfo testSessionInfo) + { + Task.Run(() => + { + var eventsHandler = new TestSessionEventsHandler(this.communicationManager); + + try + { + var stopped = TestSessionPool.Instance.KillSession(testSessionInfo); + + eventsHandler.HandleStopTestSessionComplete(testSessionInfo, stopped); + } + catch (Exception ex) + { + EqtTrace.Error("DesignModeClient: Exception in StopTestSession: " + ex); + + eventsHandler.HandleLogMessage(TestMessageLevel.Error, ex.ToString()); + eventsHandler.HandleStopTestSessionComplete(testSessionInfo, false); + } + }); + } + #region IDisposable Support private bool disposedValue = false; // To detect redundant calls diff --git a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeTestHostLauncherFactory.cs b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeTestHostLauncherFactory.cs index 8edec80450..5b92bc54ba 100644 --- a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeTestHostLauncherFactory.cs +++ b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeTestHostLauncherFactory.cs @@ -14,11 +14,11 @@ public static class DesignModeTestHostLauncherFactory private static ITestHostLauncher defaultLauncher; private static ITestHostLauncher debugLauncher; - public static ITestHostLauncher GetCustomHostLauncherForTestRun(IDesignModeClient designModeClient, TestRunRequestPayload testRunRequestPayload) + public static ITestHostLauncher GetCustomHostLauncherForTestRun(IDesignModeClient designModeClient, bool debuggingEnabled) { ITestHostLauncher testHostLauncher = null; - if (!testRunRequestPayload.DebuggingEnabled) + if (!debuggingEnabled) { testHostLauncher = defaultLauncher = defaultLauncher ?? new DesignModeTestHostLauncher(designModeClient); } diff --git a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs index 0a0e68e301..714e1df9cb 100644 --- a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs +++ b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs @@ -5,69 +5,105 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.RequestHelper { using System; using System.Collections.Generic; - + using Microsoft.VisualStudio.TestPlatform.Client; using Microsoft.VisualStudio.TestPlatform.Common.Interfaces; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads; /// - /// Defines the contract that command line + /// Defines the contract for running various requests. /// public interface ITestRequestManager : IDisposable { /// - /// Initializes the extensions while probing additional paths + /// Initializes the extensions while probing additional paths. /// - /// Paths to Additional extensions - /// Skip extension filtering by name (if true) - void InitializeExtensions(IEnumerable pathToAdditionalExtensions, bool skipExtensionFilters); + /// + /// Paths to additional extensions. + /// Skip extension filtering by name if true. + void InitializeExtensions( + IEnumerable pathToAdditionalExtensions, + bool skipExtensionFilters); /// - /// Resets Vstest.console.exe Options + /// Resets vstest.console.exe options. /// void ResetOptions(); /// - /// Discover Tests given a list of sources, runsettings + /// Discovers tests given a list of sources and some run settings. + /// + /// + /// Discovery payload. + /// Discovery events registrar. + /// Protocol related information. + void DiscoverTests( + DiscoveryRequestPayload discoveryPayload, + ITestDiscoveryEventsRegistrar disoveryEventsRegistrar, + ProtocolConfig protocolConfig); + + /// + /// Runs tests given a list of sources and some run settings. /// - /// Discovery payload - /// Discovery events registrar - registers and unregisters discovery events - /// Protocol related information - void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscoveryEventsRegistrar disoveryEventsRegistrar, ProtocolConfig protocolConfig); + /// + /// Test run request payload. + /// Custom test host launcher for the run. + /// Run events registrar. + /// Protocol related information. + void RunTests( + TestRunRequestPayload testRunRequestPayLoad, + ITestHostLauncher customTestHostLauncher, + ITestRunEventsRegistrar testRunEventsRegistrar, + ProtocolConfig protocolConfig); /// - /// Run Tests with given a test of sources + /// Processes test run attachments. /// - /// Test Run Request payload - /// Custom testHostLauncher for the run - /// RunEvents registrar - /// Protocol related information - void RunTests(TestRunRequestPayload testRunRequestPayLoad, ITestHostLauncher customTestHostLauncher, ITestRunEventsRegistrar testRunEventsRegistrar, ProtocolConfig protocolConfig); + /// + /// + /// Test run attachments processing payload. + /// + /// + /// Test run attachments processing events handler. + /// + /// Protocol related information. + void ProcessTestRunAttachments( + TestRunAttachmentsProcessingPayload testRunAttachmentsProcessingPayload, + ITestRunAttachmentsProcessingEventsHandler testRunAttachmentsProcessingEventsHandler, + ProtocolConfig protocolConfig); /// - /// Processes test run attachments + /// Starts a test session. /// - /// Test run attachments processing payload - /// Test run attachments processing events handler - void ProcessTestRunAttachments(TestRunAttachmentsProcessingPayload testRunAttachmentsProcessingPayload, ITestRunAttachmentsProcessingEventsHandler testRunAttachmentsProcessingEventsHandler, ProtocolConfig protocolConfig); + /// + /// The start test session payload. + /// The custom test host launcher. + /// The events handler. + /// Protocol related information. + void StartTestSession( + StartTestSessionPayload payload, + ITestHostLauncher testHostLauncher, + ITestSessionEventsHandler eventsHandler, + ProtocolConfig protocolConfig); /// - /// Cancel the current TestRun request + /// Cancel the current test run request. /// void CancelTestRun(); /// - /// Abort the current TestRun + /// Abort the current test run. /// void AbortTestRun(); /// - /// Cancels the current discovery request + /// Cancels the current discovery request. /// void CancelDiscovery(); /// - /// Cancels the current test run attachments processing request + /// Cancels the current test run attachments processing request. /// void CancelTestRunAttachmentsProcessing(); } diff --git a/src/Microsoft.TestPlatform.Client/TestPlatform.cs b/src/Microsoft.TestPlatform.Client/TestPlatform.cs index 8a24a51a4f..1f2915f065 100644 --- a/src/Microsoft.TestPlatform.Client/TestPlatform.cs +++ b/src/Microsoft.TestPlatform.Client/TestPlatform.cs @@ -29,7 +29,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client using ClientResources = Resources.Resources; /// - /// Implementation for TestPlatform + /// Implementation for TestPlatform. /// internal class TestPlatform : ITestPlatform { @@ -39,32 +39,34 @@ internal class TestPlatform : ITestPlatform static TestPlatform() { - // TODO This is not the right away to force initialization of default extensions. Test runtime providers - // require this today. They're getting initialized even before test adapter paths are provided, which is - // incorrect. + // TODO: This is not the right way to force initialization of default extensions. + // Test runtime providers require this today. They're getting initialized even before + // test adapter paths are provided, which is incorrect. AddExtensionAssembliesFromExtensionDirectory(); } /// /// Initializes a new instance of the class. /// - public TestPlatform() : this(new TestEngine(), new FileHelper(), TestRuntimeProviderManager.Instance) + public TestPlatform() + : this( + new TestEngine(), + new FileHelper(), + TestRuntimeProviderManager.Instance) { } /// /// Initializes a new instance of the class. /// - /// - /// The test engine. - /// - /// - /// The file helper. - /// - /// - /// The data. - /// - protected TestPlatform(ITestEngine testEngine, IFileHelper filehelper, TestRuntimeProviderManager testHostProviderManager) + /// + /// The test engine. + /// The file helper. + /// The data. + protected TestPlatform( + ITestEngine testEngine, + IFileHelper filehelper, + TestRuntimeProviderManager testHostProviderManager) { this.TestEngine = testEngine; this.fileHelper = filehelper; @@ -72,36 +74,32 @@ protected TestPlatform(ITestEngine testEngine, IFileHelper filehelper, TestRunti } /// - /// Gets or sets Test Engine instance + /// Gets or sets the test engine instance. /// private ITestEngine TestEngine { get; set; } - /// - /// The create discovery request. - /// - /// Request data. - /// The discovery criteria. - /// Test platform options. - /// The . - /// Throws if parameter is null. - public IDiscoveryRequest CreateDiscoveryRequest(IRequestData requestData, DiscoveryCriteria discoveryCriteria, TestPlatformOptions options) + /// + public IDiscoveryRequest CreateDiscoveryRequest( + IRequestData requestData, + DiscoveryCriteria discoveryCriteria, + TestPlatformOptions options) { if (discoveryCriteria == null) { throw new ArgumentNullException(nameof(discoveryCriteria)); } - // Update cache with Extension Folder's files + // Update cache with Extension folder's files. this.AddExtensionAssemblies(discoveryCriteria.RunSettings); // Update extension assemblies from source when design mode is false. var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(discoveryCriteria.RunSettings); - if (runConfiguration.DesignMode == false) + if (!runConfiguration.DesignMode) { this.AddExtensionAssembliesFromSource(discoveryCriteria.Sources); } - // Initialize loggers + // Initialize loggers. var loggerManager = this.TestEngine.GetLoggerManager(requestData); loggerManager.Initialize(discoveryCriteria.RunSettings); @@ -116,15 +114,11 @@ public IDiscoveryRequest CreateDiscoveryRequest(IRequestData requestData, Discov return new DiscoveryRequest(requestData, discoveryCriteria, discoveryManager, loggerManager); } - /// - /// The create test run request. - /// - /// Request data. - /// The test run criteria. - /// Test platform options. - /// The . - /// Throws if parameter is null. - public ITestRunRequest CreateTestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteria, TestPlatformOptions options) + /// + public ITestRunRequest CreateTestRunRequest( + IRequestData requestData, + TestRunCriteria testRunCriteria, + TestPlatformOptions options) { if (testRunCriteria == null) { @@ -141,7 +135,7 @@ public ITestRunRequest CreateTestRunRequest(IRequestData requestData, TestRunCri this.AddExtensionAssembliesFromSource(testRunCriteria); } - // Initialize loggers + // Initialize loggers. var loggerManager = this.TestEngine.GetLoggerManager(requestData); loggerManager.Initialize(testRunCriteria.TestRunSettings); @@ -150,6 +144,7 @@ public ITestRunRequest CreateTestRunRequest(IRequestData requestData, TestRunCri testHostManager.Initialize(TestSessionMessageLogger.Instance, testRunCriteria.TestRunSettings); + // NOTE: The custom launcher should not be set when we have test session info available. if (testRunCriteria.TestHostLauncher != null) { testHostManager.SetCustomLauncher(testRunCriteria.TestHostLauncher); @@ -161,6 +156,60 @@ public ITestRunRequest CreateTestRunRequest(IRequestData requestData, TestRunCri return new TestRunRequest(requestData, testRunCriteria, executionManager, loggerManager); } + /// + public void StartTestSession( + IRequestData requestData, + StartTestSessionCriteria testSessionCriteria, + ITestSessionEventsHandler eventsHandler) + { + if (testSessionCriteria == null) + { + throw new ArgumentNullException(nameof(testSessionCriteria)); + } + + this.AddExtensionAssemblies(testSessionCriteria.RunSettings); + + var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(testSessionCriteria.RunSettings); + + // Update extension assemblies from source when design mode is false. + // + // TODO (copoiena): Is it possible for this code to run if we're not in design mode ? + // An use case for this would be when running tests with "dotnet test". Usually there's + // a build involved then. + if (!runConfiguration.DesignMode) + { + return; + } + + // Initialize loggers. + var loggerManager = this.TestEngine.GetLoggerManager(requestData); + loggerManager.Initialize(testSessionCriteria.RunSettings); + + var testHostManager = this.testHostProviderManager.GetTestHostManagerByRunConfiguration(testSessionCriteria.RunSettings); + ThrowExceptionIfTestHostManagerIsNull(testHostManager, testSessionCriteria.RunSettings); + + testHostManager.Initialize(TestSessionMessageLogger.Instance, testSessionCriteria.RunSettings); + + if (testSessionCriteria.TestHostLauncher != null) + { + testHostManager.SetCustomLauncher(testSessionCriteria.TestHostLauncher); + } + + var testSessionManager = this.TestEngine.GetTestSessionManager(requestData, testHostManager, testSessionCriteria); + if (testSessionManager == null) + { + // The test session manager is null because the combination of runsettings and + // sources tells us we should run in-process (i.e. in vstest.console). Because + // of this no session will be created because there's no testhost to be launched. + // Expecting a subsequent call to execute tests with the same set of parameters. + eventsHandler.HandleStartTestSessionComplete(null); + return; + } + + testSessionManager.Initialize(false); + testSessionManager.StartSession(testSessionCriteria, eventsHandler); + } + /// /// The dispose. /// @@ -169,25 +218,23 @@ public void Dispose() throw new NotImplementedException(); } - /// - /// The update extensions. - /// - /// The path to additional extensions. - /// Skips filtering by name (if true). - public void UpdateExtensions(IEnumerable pathToAdditionalExtensions, bool skipExtensionFilters) + /// + public void UpdateExtensions( + IEnumerable pathToAdditionalExtensions, + bool skipExtensionFilters) { this.TestEngine.GetExtensionManager().UseAdditionalExtensions(pathToAdditionalExtensions, skipExtensionFilters); } - /// - /// Clears the cached extensions - /// + /// public void ClearExtensions() { this.TestEngine.GetExtensionManager().ClearExtensions(); } - private void ThrowExceptionIfTestHostManagerIsNull(ITestRuntimeProvider testHostManager, string settingXml) + private void ThrowExceptionIfTestHostManagerIsNull( + ITestRuntimeProvider testHostManager, + string settingXml) { if (testHostManager == null) { @@ -197,11 +244,11 @@ private void ThrowExceptionIfTestHostManagerIsNull(ITestRuntimeProvider testHost } /// - /// Update the test adapter paths provided through run settings to be used by the test service + /// Updates the test adapter paths provided through run settings to be used by the test + /// service. /// - /// - /// The run Settings. - /// + /// + /// The run settings. private void AddExtensionAssemblies(string runSettings) { IEnumerable customTestAdaptersPaths = RunSettingsUtilities.GetTestAdaptersPaths(runSettings); @@ -221,11 +268,14 @@ private void AddExtensionAssemblies(string runSettings) continue; } - var extensionAssemblies = new List(this.fileHelper.EnumerateFiles(adapterPath, SearchOption.AllDirectories, - TestPlatformConstants.TestAdapterEndsWithPattern, - TestPlatformConstants.TestLoggerEndsWithPattern, - TestPlatformConstants.DataCollectorEndsWithPattern, - TestPlatformConstants.RunTimeEndsWithPattern)); + var extensionAssemblies = new List( + this.fileHelper.EnumerateFiles( + adapterPath, + SearchOption.AllDirectories, + TestPlatformConstants.TestAdapterEndsWithPattern, + TestPlatformConstants.TestLoggerEndsWithPattern, + TestPlatformConstants.DataCollectorEndsWithPattern, + TestPlatformConstants.RunTimeEndsWithPattern)); if (extensionAssemblies.Count > 0) { @@ -236,17 +286,16 @@ private void AddExtensionAssemblies(string runSettings) } /// - /// Update the extension assemblies from source directory + /// Updates the extension assemblies from source directory. /// - /// - /// The test Run Criteria. - /// + /// + /// The test run criteria. private void AddExtensionAssembliesFromSource(TestRunCriteria testRunCriteria) { IEnumerable sources = testRunCriteria.Sources; if (testRunCriteria.HasSpecificTests) { - // If the test execution is with a test filter, group them by sources + // If the test execution is with a test filter, group them by sources. sources = testRunCriteria.Tests.Select(tc => tc.Source).Distinct(); } @@ -254,20 +303,26 @@ private void AddExtensionAssembliesFromSource(TestRunCriteria testRunCriteria) } /// - /// Update the test logger paths from source directory + /// Updates the test logger paths from source directory. /// - /// + /// + /// The list of sources. private void AddExtensionAssembliesFromSource(IEnumerable sources) { - // Currently we support discovering loggers only from Source directory + // Currently we support discovering loggers only from Source directory. var loggersToUpdate = new List(); foreach (var source in sources) { var sourceDirectory = Path.GetDirectoryName(source); - if (!string.IsNullOrEmpty(sourceDirectory) && this.fileHelper.DirectoryExists(sourceDirectory)) + if (!string.IsNullOrEmpty(sourceDirectory) + && this.fileHelper.DirectoryExists(sourceDirectory)) { - loggersToUpdate.AddRange(this.fileHelper.EnumerateFiles(sourceDirectory, SearchOption.TopDirectoryOnly, TestPlatformConstants.TestLoggerEndsWithPattern)); + loggersToUpdate.AddRange( + this.fileHelper.EnumerateFiles( + sourceDirectory, + SearchOption.TopDirectoryOnly, + TestPlatformConstants.TestLoggerEndsWithPattern)); } } @@ -278,16 +333,26 @@ private void AddExtensionAssembliesFromSource(IEnumerable sources) } /// - /// Find all test platform extensions from the `.\Extensions` directory. This is used to load the inbox extensions like - /// Trx logger and legacy test extensions like mstest v1, mstest c++ etc.. + /// Finds all test platform extensions from the `.\Extensions` directory. This is used to + /// load the inbox extensions like TrxLogger and legacy test extensions like MSTest v1, + /// MSTest C++, etc.. /// private static void AddExtensionAssembliesFromExtensionDirectory() { var fileHelper = new FileHelper(); - var extensionsFolder = Path.Combine(Path.GetDirectoryName(typeof(TestPlatform).GetTypeInfo().Assembly.GetAssemblyLocation()), "Extensions"); + var extensionsFolder = Path.Combine( + Path.GetDirectoryName( + typeof(TestPlatform).GetTypeInfo().Assembly.GetAssemblyLocation()), + "Extensions"); + if (fileHelper.DirectoryExists(extensionsFolder)) { - var defaultExtensionPaths = fileHelper.EnumerateFiles(extensionsFolder, SearchOption.TopDirectoryOnly, ".dll", ".exe"); + var defaultExtensionPaths = fileHelper.EnumerateFiles( + extensionsFolder, + SearchOption.TopDirectoryOnly, + ".dll", + ".exe"); + TestPluginCache.Instance.DefaultExtensionPaths = defaultExtensionPaths; } } diff --git a/src/Microsoft.TestPlatform.Client/TestSession/TestSessionEventsHandler.cs b/src/Microsoft.TestPlatform.Client/TestSession/TestSessionEventsHandler.cs new file mode 100644 index 0000000000..d5eaa5e6cc --- /dev/null +++ b/src/Microsoft.TestPlatform.Client/TestSession/TestSessionEventsHandler.cs @@ -0,0 +1,72 @@ +// 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.Client +{ + using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; + using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; + + /// + /// Defines the way in which test session events should be handled. + /// + internal class TestSessionEventsHandler : ITestSessionEventsHandler + { + private readonly ICommunicationManager communicationManager; + + /// + /// Creates an instance of the current class. + /// + /// + /// + /// The communication manager used for passing messages around. + /// + public TestSessionEventsHandler(ICommunicationManager communicationManager) + { + this.communicationManager = communicationManager; + } + + /// + public void HandleStartTestSessionComplete(TestSessionInfo testSessionInfo) + { + var ackPayload = new StartTestSessionAckPayload() + { + TestSessionInfo = testSessionInfo + }; + + this.communicationManager.SendMessage(MessageType.StartTestSessionCallback, ackPayload); + } + + /// + public void HandleStopTestSessionComplete(TestSessionInfo testSessionInfo, bool stopped) + { + var ackPayload = new StopTestSessionAckPayload() + { + TestSessionInfo = testSessionInfo, + IsStopped = stopped + }; + + this.communicationManager.SendMessage(MessageType.StopTestSessionCallback, ackPayload); + } + + /// + public void HandleLogMessage(TestMessageLevel level, string message) + { + var messagePayload = new TestMessagePayload() + { + MessageLevel = level, + Message = message + }; + + this.communicationManager.SendMessage(MessageType.TestMessage, messagePayload); + } + + /// + public void HandleRawMessage(string rawMessage) + { + // No-op. + } + } +} diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyTestSessionManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyTestSessionManager.cs new file mode 100644 index 0000000000..415974639d --- /dev/null +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyTestSessionManager.cs @@ -0,0 +1,38 @@ +// 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.ObjectModel.Engine +{ + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + + /// + /// Orchestrates test session related functionality for the engine communicating with the + /// client. + /// + public interface IProxyTestSessionManager + { + /// + /// Initialize the proxy. + /// + /// + /// Skip default adapters flag. + void Initialize(bool skipDefaultAdapters); + + /// + /// Starts the test session based on the test session criteria. + /// + /// + /// The test session criteria. + /// + /// Event handler for handling events fired during test session management operations. + /// + void StartSession( + StartTestSessionCriteria criteria, + ITestSessionEventsHandler eventsHandler); + + /// + /// Stops the test session. + /// + void StopSession(); + } +} diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/ITestEngine.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/ITestEngine.cs index 431c7c3ef1..03f2e222fb 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/ITestEngine.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/ITestEngine.cs @@ -12,37 +12,76 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine public interface ITestEngine { /// - /// Fetches the DiscoveryManager for this engine. This manager would provide all functionality required for discovery. + /// Fetches the DiscoveryManager for this engine. This manager would provide all + /// functionality required for discovery. /// - /// The Request Data for providing discovery services and data. + /// + /// + /// The request data for providing discovery services and data. + /// /// Test host manager for the current test discovery. - /// The discovery Criteria. - /// - /// ITestDiscoveryManager object that can do discovery - /// - IProxyDiscoveryManager GetDiscoveryManager(IRequestData requestData, ITestRuntimeProvider testHostManager, DiscoveryCriteria discoveryCriteria); + /// The discovery criteria. + /// + /// An IProxyDiscoveryManager object that can do discovery. + IProxyDiscoveryManager GetDiscoveryManager( + IRequestData requestData, + ITestRuntimeProvider testHostManager, + DiscoveryCriteria discoveryCriteria); /// - /// Fetches the ExecutionManager for this engine. This manager would provide all functionality required for execution. + /// Fetches the ExecutionManager for this engine. This manager would provide all + /// functionality required for execution. /// - /// The request data for providing common execution services and data - /// Test host manager for current test run. - /// TestRunCriteria of the current test run - /// ITestExecutionManager object that can do execution - IProxyExecutionManager GetExecutionManager(IRequestData requestData, ITestRuntimeProvider testHostManager, TestRunCriteria testRunCriteria); + /// + /// + /// The request data for providing common execution services and data. + /// + /// Test host manager for the current test run. + /// Test run criteria of the current test run. + /// + /// An IProxyExecutionManager object that can do execution. + IProxyExecutionManager GetExecutionManager( + IRequestData requestData, + ITestRuntimeProvider testHostManager, + TestRunCriteria testRunCriteria); + + /// + /// Fetches the TestSessionManager for this engine. This manager would provide all + /// functionality required for test session management. + /// + /// + /// + /// The request data for providing test session services and data. + /// + /// Test host manager for the current test session. + /// + /// Test session criteria of the current test session. + /// + /// + /// An IProxyTestSessionManager object that can manage test sessions. + IProxyTestSessionManager GetTestSessionManager( + IRequestData requestData, + ITestRuntimeProvider testHostManager, + StartTestSessionCriteria testSessionCriteria); /// /// Fetches the extension manager for this engine. This manager would provide extensibility /// features that this engine supports. /// - /// ITestExtensionManager object that helps with extensibility + /// + /// An ITestExtensionManager object that helps with extensibility. ITestExtensionManager GetExtensionManager(); /// - /// Fetches the logger manager for this engine. This manager will provide logger extensibility features that this engine supports. + /// Fetches the logger manager for this engine. This manager will provide logger + /// extensibility features that this engine supports. /// - /// The request data for providing common execution services and data - /// ITestLoggerManager object that helps with logger extensibility. + /// + /// + /// The request data for providing common execution services and data. + /// + /// + /// An ITestLoggerManager object that helps with logger extensibility. ITestLoggerManager GetLoggerManager(IRequestData requestData); } } diff --git a/src/Microsoft.TestPlatform.Common/Telemetry/TelemetryDataConstants.cs b/src/Microsoft.TestPlatform.Common/Telemetry/TelemetryDataConstants.cs index be35c610c2..2063d1251f 100644 --- a/src/Microsoft.TestPlatform.Common/Telemetry/TelemetryDataConstants.cs +++ b/src/Microsoft.TestPlatform.Common/Telemetry/TelemetryDataConstants.cs @@ -68,6 +68,8 @@ public static class TelemetryDataConstants public static string ParallelEnabledDuringDiscovery = "VS.TestDiscovery.ParallelEnabled"; + public static string ParallelEnabledDuringStartTestSession = "VS.StartTestSession.ParallelEnabled"; + // All the times are in sec public static string TimeTakenInSecForDiscovery = "VS.TestDiscovery.TotalTimeTakenInSec"; @@ -104,5 +106,7 @@ public static class TelemetryDataConstants public static string TestExecutionCompleteEvent = "vs/testplatform/testrunsession"; public static string TestAttachmentsProcessingCompleteEvent = "vs/testplatform/testattachmentsprocessingsession"; + + public static string StartTestSessionCompleteEvent = "vs/testplatform/starttestsession"; } } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs index 5eea4ca571..db7e58a08f 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs @@ -229,6 +229,7 @@ private JsonSerializer GetPayloadSerializer(int? version) return payloadSerializer; case 2: case 4: + case 5: return payloadSerializer2; default: throw new NotSupportedException($"Protocol version {version} is not supported. " + diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/MessageType.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/MessageType.cs index 76cfeec873..0a92bbc38b 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/MessageType.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/MessageType.cs @@ -193,6 +193,26 @@ public static class MessageType /// public const string DataCollectionMessage = "DataCollection.SendMessage"; + /// + /// StartTestSession message. + /// + public const string StartTestSession = "TestSession.StartTestSession"; + + /// + /// StartTestSession callback message. + /// + public const string StartTestSessionCallback = "TestSession.StartTestSessionCallback"; + + /// + /// StopTestSession message. + /// + public const string StopTestSession = "TestSession.StopTestSession"; + + /// + /// StopTestSession callback message. + /// + public const string StopTestSessionCallback = "TestSession.StopTestSessionCallback"; + #region DataCollector messages /// diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs index e0896ab338..df3bc35603 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs @@ -52,8 +52,9 @@ public class TestRequestSender : ITestRequestSender // that implies host is using version 1. private int protocolVersion = 1; - // Also check TestRequestHandler. - private int highestSupportedVersion = 4; + // Must be in sync with the highest supported version in + // src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs file. + private int highestSupportedVersion = 5; private TestHostConnectionInfo connectionInfo; @@ -733,4 +734,4 @@ private void SetCommunicationEndPoint() } } } -} \ No newline at end of file +} diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/Interfaces/ITestPlatformEventSource.cs b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/Interfaces/ITestPlatformEventSource.cs index 7f88ccbf83..767d09cf83 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/Interfaces/ITestPlatformEventSource.cs +++ b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/Interfaces/ITestPlatformEventSource.cs @@ -218,5 +218,45 @@ public interface ITestPlatformEventSource /// Mark the completion of translation layer test run attachments processing request. /// void TranslationLayerTestRunAttachmentsProcessingStop(); + + /// + /// The start of the test session start request. + /// + void StartTestSessionStart(); + + /// + /// The end of the test session start request. + /// + void StartTestSessionStop(); + + /// + /// Mark the start of a translation layer start test session request. + /// + void TranslationLayerStartTestSessionStart(); + + /// + /// Mark the end of a translation layer start test session request. + /// + void TranslationLayerStartTestSessionStop(); + + /// + /// The start of the test session stop request. + /// + void StopTestSessionStart(); + + /// + /// The end of the test session stop request. + /// + void StopTestSessionStop(); + + /// + /// Mark the start of a translation layer stop test session request. + /// + void TranslationLayerStopTestSessionStart(); + + /// + /// Mark the end of a translation layer stop test session request. + /// + void TranslationLayerStopTestSessionStop(); } } diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/TestPlatformEventSource.cs b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/TestPlatformEventSource.cs index 7db7ffe6e4..3ad391be38 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/TestPlatformEventSource.cs +++ b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/TestPlatformEventSource.cs @@ -282,6 +282,62 @@ public void TranslationLayerTestRunAttachmentsProcessingStop() { this.WriteEvent(TestPlatformInstrumentationEvents.TranslationLayerTestRunAttachmentsProcessingStopEventId); } + + /// + [Event(TestPlatformInstrumentationEvents.StartTestSessionStartEventId)] + public void StartTestSessionStart() + { + this.WriteEvent(TestPlatformInstrumentationEvents.StartTestSessionStartEventId); + } + + /// + [Event(TestPlatformInstrumentationEvents.StartTestSessionStopEventId)] + public void StartTestSessionStop() + { + this.WriteEvent(TestPlatformInstrumentationEvents.StartTestSessionStopEventId); + } + + /// + [Event(TestPlatformInstrumentationEvents.TranslationLayerStartTestSessionStartEventId)] + public void TranslationLayerStartTestSessionStart() + { + this.WriteEvent(TestPlatformInstrumentationEvents.TranslationLayerStartTestSessionStartEventId); + } + + /// + [Event(TestPlatformInstrumentationEvents.TranslationLayerStartTestSessionStopEventId)] + public void TranslationLayerStartTestSessionStop() + { + this.WriteEvent(TestPlatformInstrumentationEvents.TranslationLayerStartTestSessionStopEventId); + } + + /// + [Event(TestPlatformInstrumentationEvents.StopTestSessionStartEventId)] + public void StopTestSessionStart() + { + this.WriteEvent(TestPlatformInstrumentationEvents.StopTestSessionStartEventId); + } + + /// + [Event(TestPlatformInstrumentationEvents.StopTestSessionStopEventId)] + public void StopTestSessionStop() + { + this.WriteEvent(TestPlatformInstrumentationEvents.StopTestSessionStopEventId); + } + + /// + [Event(TestPlatformInstrumentationEvents.TranslationLayerStopTestSessionStartEventId)] + public void TranslationLayerStopTestSessionStart() + { + this.WriteEvent(TestPlatformInstrumentationEvents.TranslationLayerStopTestSessionStartEventId); + } + + /// + [Event(TestPlatformInstrumentationEvents.TranslationLayerStopTestSessionStopEventId)] + public void TranslationLayerStopTestSessionStop() + { + this.WriteEvent(TestPlatformInstrumentationEvents.TranslationLayerStopTestSessionStopEventId); + } } } diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/TestPlatformInstrumentationEvents.cs b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/TestPlatformInstrumentationEvents.cs index 1aa2311048..51e8fec9ba 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/TestPlatformInstrumentationEvents.cs +++ b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/TestPlatformInstrumentationEvents.cs @@ -187,5 +187,45 @@ internal class TestPlatformInstrumentationEvents /// Events fired on session attachments processing complete in translation layer. /// public const int TranslationLayerTestRunAttachmentsProcessingStopEventId = 0x45; + + /// + /// The start test session start event id. + /// + public const int StartTestSessionStartEventId = 0x46; + + /// + /// The start test session stop event id. + /// + public const int StartTestSessionStopEventId = 0x47; + + /// + /// The translation layer start test session start event id. + /// + public const int TranslationLayerStartTestSessionStartEventId = 0x48; + + /// + /// The translation layer start test session stop event id. + /// + public const int TranslationLayerStartTestSessionStopEventId = 0x49; + + /// + /// The stop test session start event id. + /// + public const int StopTestSessionStartEventId = 0x4A; + + /// + /// The stop test session stop event id. + /// + public const int StopTestSessionStopEventId = 0x4B; + + /// + /// The translation layer stop test session start event id. + /// + public const int TranslationLayerStopTestSessionStartEventId = 0x4C; + + /// + /// The translation layer stop test session stop event id. + /// + public const int TranslationLayerStopTestSessionStopEventId = 0x4D; } } \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs index 07158a8106..7623603154 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs @@ -23,8 +23,9 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client /// /// Orchestrates discovery operations for the engine communicating with the client. /// - public class ProxyDiscoveryManager : ProxyOperationManager, IProxyDiscoveryManager, ITestDiscoveryEventsHandler2 + public class ProxyDiscoveryManager : IProxyDiscoveryManager, IBaseProxy, ITestDiscoveryEventsHandler2 { + private ProxyOperationManager proxyOperationManager; private readonly ITestRuntimeProvider testHostManager; private IDataSerializer dataSerializer; private bool isCommunicationEstablished; @@ -38,72 +39,82 @@ public class ProxyDiscoveryManager : ProxyOperationManager, IProxyDiscoveryManag /// /// Initializes a new instance of the class. /// - /// The Request Data for providing discovery services and data. + /// + /// + /// The request data for providing discovery services and data. + /// /// Test request sender instance. /// Test host manager instance. - public ProxyDiscoveryManager(IRequestData requestData, ITestRequestSender testRequestSender, ITestRuntimeProvider testHostManager) - : this(requestData, testRequestSender, testHostManager, JsonDataSerializer.Instance, new FileHelper()) + public ProxyDiscoveryManager( + IRequestData requestData, + ITestRequestSender testRequestSender, + ITestRuntimeProvider testHostManager) + : this( + requestData, + testRequestSender, + testHostManager, + JsonDataSerializer.Instance, + new FileHelper()) { this.testHostManager = testHostManager; } /// /// Initializes a new instance of the class. - /// Constructor with Dependency injection. Used for unit testing. /// - /// - /// - /// The request Sender. - /// - /// - /// Test host Manager instance + /// + /// + /// Constructor with dependency injection. Used for unit testing. + /// + /// + /// + /// The request data for providing discovery services and data. /// - /// - internal ProxyDiscoveryManager(IRequestData requestData, + /// The request sender. + /// Test host manager instance. + /// The data serializer. + /// The file helper. + internal ProxyDiscoveryManager( + IRequestData requestData, ITestRequestSender requestSender, ITestRuntimeProvider testHostManager, IDataSerializer dataSerializer, IFileHelper fileHelper) - : base(requestData, requestSender, testHostManager) { this.dataSerializer = dataSerializer; this.testHostManager = testHostManager; this.isCommunicationEstablished = false; this.requestData = requestData; this.fileHelper = fileHelper; + + // Create a new proxy operation manager. + this.proxyOperationManager = new ProxyOperationManager(requestData, requestSender, testHostManager, this); } #endregion #region IProxyDiscoveryManager implementation. - /// - /// Ensure that the discovery component of engine is ready for discovery usually by loading extensions. - /// Skip default adapters flag. - /// + /// public void Initialize(bool skipDefaultAdapters) { this.skipDefaultAdapters = skipDefaultAdapters; } - /// - /// Discovers tests - /// - /// Settings, parameters for the discovery request - /// EventHandler for handling discovery events from Engine + /// public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler2 eventHandler) { this.baseTestDiscoveryEventsHandler = eventHandler; try { - this.isCommunicationEstablished = this.SetupChannel(discoveryCriteria.Sources, discoveryCriteria.RunSettings); + this.isCommunicationEstablished = this.proxyOperationManager.SetupChannel(discoveryCriteria.Sources, discoveryCriteria.RunSettings); if (this.isCommunicationEstablished) { this.InitializeExtensions(discoveryCriteria.Sources); discoveryCriteria.UpdateDiscoveryCriteria(testHostManager); - this.RequestSender.DiscoverTests(discoveryCriteria, this); + this.proxyOperationManager.RequestSender.DiscoverTests(discoveryCriteria, this); } } catch (Exception exception) @@ -139,10 +150,16 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve public void Abort() { // Cancel fast, try to stop testhost deployment/launch - this.CancellationTokenSource.Cancel(); + this.proxyOperationManager.CancellationTokenSource.Cancel(); this.Close(); } + /// + public void Close() + { + this.proxyOperationManager.Close(); + } + /// public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryCompleteEventArgs, IEnumerable lastChunk) { @@ -175,6 +192,17 @@ public void HandleLogMessage(TestMessageLevel level, string message) #endregion + #region IBaseProxy implementation. + /// + public virtual TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) + { + // Update Telemetry Opt in status because by default in Test Host Telemetry is opted out + var telemetryOptedIn = this.proxyOperationManager.RequestData.IsTelemetryOptedIn ? "true" : "false"; + testProcessStartInfo.Arguments += " --telemetryoptedin " + telemetryOptedIn; + return testProcessStartInfo; + } + #endregion + private void InitializeExtensions(IEnumerable sources) { var extensions = TestPluginCache.Instance.GetExtensionPaths(TestPlatformConstants.TestAdapterEndsWithPattern, this.skipDefaultAdapters); @@ -192,7 +220,7 @@ private void InitializeExtensions(IEnumerable sources) // Only send this if needed. if (platformExtensions.Any()) { - this.RequestSender.InitializeDiscovery(platformExtensions); + this.proxyOperationManager.RequestSender.InitializeDiscovery(platformExtensions); } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManager.cs index ba157953ef..b16d5ef3e9 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManager.cs @@ -6,8 +6,8 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client using System; using System.Collections.Generic; using System.Collections.ObjectModel; - using System.Globalization; using System.Linq; + using System.Threading; using Microsoft.VisualStudio.TestPlatform.Common; using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework; @@ -15,6 +15,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; @@ -27,71 +28,121 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client /// /// Orchestrates test execution operations for the engine communicating with the client. /// - internal class ProxyExecutionManager : ProxyOperationManager, IProxyExecutionManager, ITestRunEventsHandler2 + internal class ProxyExecutionManager : IProxyExecutionManager, IBaseProxy, ITestRunEventsHandler2 { private readonly ITestRuntimeProvider testHostManager; - private IDataSerializer dataSerializer; + private readonly IFileHelper fileHelper; + private bool isCommunicationEstablished; + private bool skipDefaultAdapters; + private IDataSerializer dataSerializer; private IRequestData requestData; private ITestRunEventsHandler baseTestRunEventsHandler; - private bool skipDefaultAdapters; - private readonly IFileHelper fileHelper; + private TestSessionInfo testSessionInfo = null; + private bool debugEnabledForTestSession = false; /// public bool IsInitialized { get; private set; } = false; + /// + /// Gets or sets the cancellation token source. + /// + public CancellationTokenSource CancellationTokenSource + { + get { return this.ProxyOperationManager.CancellationTokenSource; } + set { this.ProxyOperationManager.CancellationTokenSource = value; } + } + + protected ProxyOperationManager ProxyOperationManager { get; set; } #region Constructors /// /// Initializes a new instance of the class. /// - /// The Request Data for providing services and data for Run. + /// + /// The test session info. + /// + /// A flag indicating if debugging should be enabled or not. + /// + public ProxyExecutionManager(TestSessionInfo testSessionInfo, bool debugEnabledForTestSession) + { + // Filling in test session info and proxy information. + this.testSessionInfo = testSessionInfo; + this.ProxyOperationManager = TestSessionPool.Instance.TakeProxy(this.testSessionInfo); + // This should be set to enable debugging when we have test session info available. + this.debugEnabledForTestSession = debugEnabledForTestSession; + + this.testHostManager = this.ProxyOperationManager.TestHostManager; + this.dataSerializer = JsonDataSerializer.Instance; + this.isCommunicationEstablished = false; + this.requestData = this.ProxyOperationManager.RequestData; + this.fileHelper = new FileHelper(); + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// The request data for providing services and data for run. + /// /// Test request sender instance. /// Test host manager for this proxy. - public ProxyExecutionManager(IRequestData requestData, ITestRequestSender requestSender, ITestRuntimeProvider testHostManager) : - this(requestData, requestSender, testHostManager, JsonDataSerializer.Instance, new FileHelper()) + public ProxyExecutionManager( + IRequestData requestData, + ITestRequestSender requestSender, + ITestRuntimeProvider testHostManager) : + this( + requestData, + requestSender, + testHostManager, + JsonDataSerializer.Instance, + new FileHelper()) { } /// /// Initializes a new instance of the class. - /// Constructor with Dependency injection. Used for unit testing. /// - /// The Request Data for Common services and data for Run. - /// Request Sender instance - /// Test host manager instance - /// - internal ProxyExecutionManager(IRequestData requestData, ITestRequestSender requestSender, - ITestRuntimeProvider testHostManager, IDataSerializer dataSerializer, IFileHelper fileHelper) - : base(requestData, requestSender, testHostManager) + /// + /// + /// Constructor with dependency injection. Used for unit testing. + /// + /// + /// The request data for common services and data for run. + /// Request sender instance. + /// Test host manager instance. + /// Data serializer instance. + /// File helper instance. + internal ProxyExecutionManager( + IRequestData requestData, + ITestRequestSender requestSender, + ITestRuntimeProvider testHostManager, + IDataSerializer dataSerializer, + IFileHelper fileHelper) { this.testHostManager = testHostManager; this.dataSerializer = dataSerializer; this.isCommunicationEstablished = false; this.requestData = requestData; this.fileHelper = fileHelper; + + // Create a new proxy operation manager. + this.ProxyOperationManager = new ProxyOperationManager(requestData, requestSender, testHostManager, this); } #endregion #region IProxyExecutionManager implementation. - /// - /// Ensure that the Execution component of engine is ready for execution usually by loading extensions. - /// Skip default adapters flag. - /// + /// public virtual void Initialize(bool skipDefaultAdapters) { this.skipDefaultAdapters = skipDefaultAdapters; this.IsInitialized = true; } - /// - /// Starts the test run - /// - /// The settings/options for the test run. - /// EventHandler for handling execution events from Engine. - /// The process id of the runner executing tests. + /// public virtual int StartTestRun(TestRunCriteria testRunCriteria, ITestRunEventsHandler eventHandler) { this.baseTestRunEventsHandler = eventHandler; @@ -103,19 +154,24 @@ public virtual int StartTestRun(TestRunCriteria testRunCriteria, ITestRunEventsH EqtTrace.Verbose("ProxyExecutionManager: Test host is always Lazy initialize."); } - var testSources = new List(testRunCriteria.HasSpecificSources ? testRunCriteria.Sources : - // If the test execution is with a test filter, group them by sources - testRunCriteria.Tests.GroupBy(tc => tc.Source).Select(g => g.Key)); + var testSources = new List( + testRunCriteria.HasSpecificSources + ? testRunCriteria.Sources + // If the test execution is with a test filter, group them by sources. + : testRunCriteria.Tests.GroupBy(tc => tc.Source).Select(g => g.Key)); - this.isCommunicationEstablished = this.SetupChannel(testSources, testRunCriteria.TestRunSettings); + this.isCommunicationEstablished = this.ProxyOperationManager.SetupChannel( + testSources, + testRunCriteria.TestRunSettings); if (this.isCommunicationEstablished) { - this.CancellationTokenSource.Token.ThrowTestPlatformExceptionIfCancellationRequested(); + this.ProxyOperationManager.CancellationTokenSource.Token.ThrowTestPlatformExceptionIfCancellationRequested(); this.InitializeExtensions(testSources); - // This code should be in sync with InProcessProxyExecutionManager.StartTestRun executionContext + // This code should be in sync with InProcessProxyExecutionManager.StartTestRun + // execution context. var executionContext = new TestExecutionContext( testRunCriteria.FrequencyOfRunStatsChangeEvent, testRunCriteria.RunStatsChangeEventTimeout, @@ -124,22 +180,37 @@ public virtual int StartTestRun(TestRunCriteria testRunCriteria, ITestRunEventsH isDataCollectionEnabled: false, areTestCaseLevelEventsRequired: false, hasTestRun: true, - isDebug: (testRunCriteria.TestHostLauncher != null && testRunCriteria.TestHostLauncher.IsDebug), + // Debugging should happen if there's a custom test host launcher present + // and is in debugging mode, or if the debugging is enabled in case the + // test session info is present. + isDebug: + (testRunCriteria.TestHostLauncher != null && testRunCriteria.TestHostLauncher.IsDebug) + || this.debugEnabledForTestSession, testCaseFilter: testRunCriteria.TestCaseFilter, filterOptions: testRunCriteria.FilterOptions); // This is workaround for the bug https://github.com/Microsoft/vstest/issues/970 - var runsettings = this.RemoveNodesFromRunsettingsIfRequired(testRunCriteria.TestRunSettings, (testMessageLevel, message) => { this.LogMessage(testMessageLevel, message); }); + var runsettings = this.ProxyOperationManager.RemoveNodesFromRunsettingsIfRequired( + testRunCriteria.TestRunSettings, + (testMessageLevel, message) => { this.LogMessage(testMessageLevel, message); }); if (testRunCriteria.HasSpecificSources) { - var runRequest = testRunCriteria.CreateTestRunCriteriaForSources(testHostManager, runsettings, executionContext, testSources); - this.RequestSender.StartTestRun(runRequest, this); + var runRequest = testRunCriteria.CreateTestRunCriteriaForSources( + testHostManager, + runsettings, + executionContext, + testSources); + this.ProxyOperationManager.RequestSender.StartTestRun(runRequest, this); } else { - var runRequest = testRunCriteria.CreateTestRunCriteriaForTests(testHostManager, runsettings, executionContext, testSources); - this.RequestSender.StartTestRun(runRequest, this); + var runRequest = testRunCriteria.CreateTestRunCriteriaForTests( + testHostManager, + runsettings, + executionContext, + testSources); + this.ProxyOperationManager.RequestSender.StartTestRun(runRequest, this); } } } @@ -148,17 +219,24 @@ public virtual int StartTestRun(TestRunCriteria testRunCriteria, ITestRunEventsH EqtTrace.Error("ProxyExecutionManager.StartTestRun: Failed to start test run: {0}", exception); // Log error message to design mode and CLI. - // TestPlatformException is expected exception, log only the message - // For other exceptions, log the stacktrace as well + // TestPlatformException is expected exception, log only the message. + // For other exceptions, log the stacktrace as well. var errorMessage = exception is TestPlatformException ? exception.Message : exception.ToString(); - var testMessagePayload = new TestMessagePayload { MessageLevel = TestMessageLevel.Error, Message = errorMessage }; + var testMessagePayload = new TestMessagePayload() + { + MessageLevel = TestMessageLevel.Error, + Message = errorMessage + }; this.HandleRawMessage(this.dataSerializer.SerializePayload(MessageType.TestMessage, testMessagePayload)); this.LogMessage(TestMessageLevel.Error, errorMessage); - // Send a run complete to caller. Similar logic is also used in ParallelProxyExecutionManager.StartTestRunOnConcurrentManager - // Aborted is `true`: in case of parallel run (or non shared host), an aborted message ensures another execution manager - // created to replace the current one. This will help if the current execution manager is aborted due to irreparable error - // and the test host is lost as well. + // Send a run complete to caller. Similar logic is also used in + // ParallelProxyExecutionManager.StartTestRunOnConcurrentManager. + // + // Aborted is `true`: in case of parallel run (or non shared host), an aborted + // message ensures another execution manager created to replace the current one. + // This will help if the current execution manager is aborted due to irreparable + // error and the test host is lost as well. var completeArgs = new TestRunCompleteEventArgs(null, false, true, null, new Collection(), TimeSpan.Zero); var testRunCompletePayload = new TestRunCompletePayload { TestRunCompleteArgs = completeArgs }; this.HandleRawMessage(this.dataSerializer.SerializePayload(MessageType.ExecutionComplete, testRunCompletePayload)); @@ -168,62 +246,68 @@ public virtual int StartTestRun(TestRunCriteria testRunCriteria, ITestRunEventsH return 0; } - /// - /// Cancels the test run. - /// - /// EventHandler for handling execution events from Engine. + /// public virtual void Cancel(ITestRunEventsHandler eventHandler) { - // Just in case ExecuteAsync isn't called yet, set the eventhandler + // Just in case ExecuteAsync isn't called yet, set the eventhandler. if (this.baseTestRunEventsHandler == null) { this.baseTestRunEventsHandler = eventHandler; } - // Cancel fast, try to stop testhost deployment/launch - this.CancellationTokenSource.Cancel(); + // Cancel fast, try to stop testhost deployment/launch. + this.ProxyOperationManager.CancellationTokenSource.Cancel(); if (this.isCommunicationEstablished) { - this.RequestSender.SendTestRunCancel(); + this.ProxyOperationManager.RequestSender.SendTestRunCancel(); } } /// - public virtual int LaunchProcessWithDebuggerAttached(TestProcessStartInfo testProcessStartInfo) - { - return this.baseTestRunEventsHandler.LaunchProcessWithDebuggerAttached(testProcessStartInfo); - } - - /// - public bool AttachDebuggerToProcess(int pid) - { - return ((ITestRunEventsHandler2)this.baseTestRunEventsHandler).AttachDebuggerToProcess(pid); - } - - /// - /// Aborts the test run. - /// - /// EventHandler for handling execution events from Engine. public void Abort(ITestRunEventsHandler eventHandler) { - // Just in case ExecuteAsync isn't called yet, set the eventhandler + // Just in case ExecuteAsync isn't called yet, set the eventhandler. if (this.baseTestRunEventsHandler == null) { this.baseTestRunEventsHandler = eventHandler; } - // Cancel fast, try to stop testhost deployment/launch - this.CancellationTokenSource.Cancel(); + // Cancel fast, try to stop testhost deployment/launch. + this.ProxyOperationManager.CancellationTokenSource.Cancel(); if (this.isCommunicationEstablished) { - this.RequestSender.SendTestRunAbort(); + this.ProxyOperationManager.RequestSender.SendTestRunAbort(); } } + /// + public void Close() + { + this.ProxyOperationManager.Close(); + } + + /// + public virtual int LaunchProcessWithDebuggerAttached(TestProcessStartInfo testProcessStartInfo) + { + return this.baseTestRunEventsHandler.LaunchProcessWithDebuggerAttached(testProcessStartInfo); + } + + /// + public bool AttachDebuggerToProcess(int pid) + { + return ((ITestRunEventsHandler2)this.baseTestRunEventsHandler).AttachDebuggerToProcess(pid); + } + /// public void HandleTestRunComplete(TestRunCompleteEventArgs testRunCompleteArgs, TestRunChangedEventArgs lastChunkArgs, ICollection runContextAttachments, ICollection executorUris) { + if (this.testSessionInfo != null) + { + // TODO (copoiena): Is returning the proxy to the pool here enough ? + TestSessionPool.Instance.ReturnProxy(this.testSessionInfo, this.ProxyOperationManager.Id); + } + this.baseTestRunEventsHandler.HandleTestRunComplete(testRunCompleteArgs, lastChunkArgs, runContextAttachments, executorUris); } @@ -246,6 +330,7 @@ public void HandleRawMessage(string rawMessage) this.baseTestRunEventsHandler.HandleRawMessage(rawMessage); } + /// public void HandleLogMessage(TestMessageLevel level, string message) { this.baseTestRunEventsHandler.HandleLogMessage(level, message); @@ -253,14 +338,41 @@ public void HandleLogMessage(TestMessageLevel level, string message) #endregion + #region IBaseProxy implementation. + /// + public virtual TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) + { + // Update Telemetry Opt in status because by default in Test Host Telemetry is opted out + var telemetryOptedIn = this.ProxyOperationManager.RequestData.IsTelemetryOptedIn ? "true" : "false"; + testProcessStartInfo.Arguments += " --telemetryoptedin " + telemetryOptedIn; + return testProcessStartInfo; + } + #endregion + + /// + /// Ensures that the engine is ready for test operations. Usually includes starting up the + /// test host process. + /// + /// + /// List of test sources. + /// Run settings to be used. + /// + /// + /// Returns true if the communication is established b/w runner and host, false otherwise. + /// + public virtual bool SetupChannel(IEnumerable sources, string runSettings) + { + return this.ProxyOperationManager.SetupChannel(sources, runSettings); + } + private void LogMessage(TestMessageLevel testMessageLevel, string message) { - // Log to vs ide test output + // Log to vs ide test output. var testMessagePayload = new TestMessagePayload { MessageLevel = testMessageLevel, Message = message }; var rawMessage = this.dataSerializer.SerializePayload(MessageType.TestMessage, testMessagePayload); this.HandleRawMessage(rawMessage); - // Log to vstest.console + // Log to vstest.console. this.HandleLogMessage(testMessageLevel, message); } @@ -268,7 +380,7 @@ private void InitializeExtensions(IEnumerable sources) { var extensions = TestPluginCache.Instance.GetExtensionPaths(TestPlatformConstants.TestAdapterEndsWithPattern, this.skipDefaultAdapters); - // Filter out non existing extensions + // Filter out non existing extensions. var nonExistingExtensions = extensions.Where(extension => !this.fileHelper.Exists(extension)); if (nonExistingExtensions.Any()) { @@ -281,7 +393,7 @@ private void InitializeExtensions(IEnumerable sources) // Only send this if needed. if (platformExtensions.Any()) { - this.RequestSender.InitializeExecution(platformExtensions); + this.ProxyOperationManager.RequestSender.InitializeExecution(platformExtensions); } } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManagerWithDataCollection.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManagerWithDataCollection.cs index 179a6df370..8aad17856d 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManagerWithDataCollection.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManagerWithDataCollection.cs @@ -38,8 +38,15 @@ internal class ProxyExecutionManagerWithDataCollection : ProxyExecutionManager /// /// The request data for providing execution services and data. /// - public ProxyExecutionManagerWithDataCollection(IRequestData requestData, ITestRequestSender requestSender, ITestRuntimeProvider testHostManager, IProxyDataCollectionManager proxyDataCollectionManager) - : base(requestData, requestSender, testHostManager) + public ProxyExecutionManagerWithDataCollection( + IRequestData requestData, + ITestRequestSender requestSender, + ITestRuntimeProvider testHostManager, + IProxyDataCollectionManager proxyDataCollectionManager) + : base( + requestData, + requestSender, + testHostManager) { this.ProxyDataCollectionManager = proxyDataCollectionManager; this.DataCollectionRunEventsHandler = new DataCollectionRunEventsHandler(); @@ -160,7 +167,7 @@ public override int LaunchProcessWithDebuggerAttached(TestProcessStartInfo testP } /// - protected override TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) + public override TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) { if (testProcessStartInfo.EnvironmentVariables == null) { diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs index aa0c7a40a0..81e83f2e7d 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs @@ -10,7 +10,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client using System.Linq; using System.Reflection; using System.Threading; - using CoreUtilities.Helpers; + using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; using Microsoft.VisualStudio.TestPlatform.Common.Utilities; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Extensions; @@ -22,189 +22,284 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces; using Microsoft.VisualStudio.TestPlatform.Utilities; - using CrossPlatEngineResources = Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Resources.Resources; - using CommunicationUtilitiesResources = Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Resources.Resources; - using CoreUtilitiesConstants = Microsoft.VisualStudio.TestPlatform.CoreUtilities.Constants; + using CoreUtilities.Helpers; + + using CrossPlatEngineResources = Resources.Resources; + using CommunicationUtilitiesResources = CommunicationUtilities.Resources.Resources; + using CoreUtilitiesConstants = CoreUtilities.Constants; /// /// Base class for any operations that the client needs to drive through the engine. /// - public abstract class ProxyOperationManager + public class ProxyOperationManager { - private readonly ITestRuntimeProvider testHostManager; - private readonly IProcessHelper processHelper; private readonly string versionCheckPropertyName = "IsVersionCheckRequired"; private readonly string makeRunsettingsCompatiblePropertyName = "MakeRunsettingsCompatible"; + private readonly Guid id = Guid.NewGuid(); + private readonly ManualResetEventSlim testHostExited = new ManualResetEventSlim(false); + private readonly IProcessHelper processHelper; + + private IBaseProxy baseProxy; private bool versionCheckRequired = true; private bool makeRunsettingsCompatible; private bool makeRunsettingsCompatibleSet; - private readonly ManualResetEventSlim testHostExited = new ManualResetEventSlim(false); - - private int testHostProcessId; private bool initialized; - private string testHostProcessStdError; private bool testHostLaunched; - private IRequestData requestData; + private int testHostProcessId; + private string testHostProcessStdError; #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// + /// Request data instance. + /// Request sender instance. + /// Test host manager instance. + public ProxyOperationManager( + IRequestData requestData, + ITestRequestSender requestSender, + ITestRuntimeProvider testHostManager) + : this( + requestData, + requestSender, + testHostManager, + null) + { } /// /// Initializes a new instance of the class. /// - /// - /// Request Sender instance. + /// + /// Request data instance. + /// Request sender instance. /// Test host manager instance. - protected ProxyOperationManager(IRequestData requestData, ITestRequestSender requestSender, ITestRuntimeProvider testHostManager) + /// The base proxy. + public ProxyOperationManager( + IRequestData requestData, + ITestRequestSender requestSender, + ITestRuntimeProvider testHostManager, + IBaseProxy baseProxy) { + this.RequestData = requestData; this.RequestSender = requestSender; - this.CancellationTokenSource = new CancellationTokenSource(); - this.testHostManager = testHostManager; - this.processHelper = new ProcessHelper(); + this.TestHostManager = testHostManager; + this.baseProxy = baseProxy; + this.initialized = false; this.testHostLaunched = false; this.testHostProcessId = -1; - this.requestData = requestData; + this.processHelper = new ProcessHelper(); + this.CancellationTokenSource = new CancellationTokenSource(); } #endregion #region Properties + /// + /// Gets or sets the request data. + /// + public IRequestData RequestData { get; set; } /// /// Gets or sets the server for communication. /// - protected ITestRequestSender RequestSender { get; set; } + public ITestRequestSender RequestSender { get; set; } /// - /// Gets or sets the cancellation token source. + /// Gets or sets the test host manager. + /// + public ITestRuntimeProvider TestHostManager { get; set; } + + /// + /// Gets the proxy operation manager id. /// - protected CancellationTokenSource CancellationTokenSource { get; set; } + public Guid Id { get { return this.id; } } + /// + /// Gets or sets the cancellation token source. + /// + public CancellationTokenSource CancellationTokenSource { get; set; } #endregion #region IProxyOperationManager implementation. - /// - /// Ensure that the engine is ready for test operations. - /// Usually includes starting up the test host process. + /// Initializes the proxy. /// - /// - /// List of test sources. - /// - /// + /// + /// + /// Flag indicating if we should skip the default adapters initialization. /// + public virtual void Initialize(bool skipDefaultAdapters) + { + // No-op. + } + + /// + /// Ensures that the engine is ready for test operations. Usually includes starting up the + /// test host process. + /// + /// + /// List of test sources. + /// Run settings to be used. + /// The events handler. + /// /// - /// Returns true if Communication is established b/w runner and host + /// Returns true if the communication is established b/w runner and host, false otherwise. + /// + public virtual bool SetupChannel( + IEnumerable sources, + string runSettings, + ITestMessageEventHandler eventHandler) + { + return this.SetupChannel(sources, runSettings); + } + + /// + /// Ensures that the engine is ready for test operations. Usually includes starting up the + /// test host process. + /// + /// + /// List of test sources. + /// Run settings to be used. + /// + /// + /// Returns true if the communication is established b/w runner and host, false otherwise. /// public virtual bool SetupChannel(IEnumerable sources, string runSettings) { this.CancellationTokenSource.Token.ThrowTestPlatformExceptionIfCancellationRequested(); - var connTimeout = EnvironmentHelper.GetConnectionTimeout(); - if (!this.initialized) + if (this.initialized) { - this.testHostProcessStdError = string.Empty; - TestHostConnectionInfo testHostConnectionInfo = this.testHostManager.GetTestHostConnectionInfo(); - - var portNumber = 0; - - if (testHostConnectionInfo.Role == ConnectionRole.Client) - { - portNumber = this.RequestSender.InitializeCommunication(); - testHostConnectionInfo.Endpoint += portNumber; - } + return true; + } - var processId = this.processHelper.GetCurrentProcessId(); - var connectionInfo = new TestRunnerConnectionInfo { Port = portNumber, ConnectionInfo = testHostConnectionInfo, RunnerProcessId = processId, LogFile = this.GetTimestampedLogFile(EqtTrace.LogFile), TraceLevel = (int)EqtTrace.TraceLevel }; + var connTimeout = EnvironmentHelper.GetConnectionTimeout(); - // Subscribe to TestHost Event - this.testHostManager.HostLaunched += this.TestHostManagerHostLaunched; - this.testHostManager.HostExited += this.TestHostManagerHostExited; + this.testHostProcessStdError = string.Empty; + TestHostConnectionInfo testHostConnectionInfo = this.TestHostManager.GetTestHostConnectionInfo(); + + var portNumber = 0; + if (testHostConnectionInfo.Role == ConnectionRole.Client) + { + portNumber = this.RequestSender.InitializeCommunication(); + testHostConnectionInfo.Endpoint += portNumber; + } - // Get envVars from run settings - var envVars = InferRunSettingsHelper.GetEnvironmentVariables(runSettings); + var processId = this.processHelper.GetCurrentProcessId(); + var connectionInfo = new TestRunnerConnectionInfo() + { + Port = portNumber, + ConnectionInfo = testHostConnectionInfo, + RunnerProcessId = processId, + LogFile = this.GetTimestampedLogFile(EqtTrace.LogFile), + TraceLevel = (int)EqtTrace.TraceLevel + }; + + // Subscribe to test host events. + this.TestHostManager.HostLaunched += this.TestHostManagerHostLaunched; + this.TestHostManager.HostExited += this.TestHostManagerHostExited; + + // Get environment variables from run settings. + var envVars = InferRunSettingsHelper.GetEnvironmentVariables(runSettings); + + // Get the test process start info. + var testHostStartInfo = this.UpdateTestProcessStartInfo( + this.TestHostManager.GetTestHostProcessStartInfo( + sources, + envVars, + connectionInfo)); + try + { + // Launch the test host. + var hostLaunchedTask = this.TestHostManager.LaunchTestHostAsync( + testHostStartInfo, + this.CancellationTokenSource.Token); + this.testHostLaunched = hostLaunchedTask.Result; - // Get the test process start info - var testHostStartInfo = this.UpdateTestProcessStartInfo(this.testHostManager.GetTestHostProcessStartInfo(sources, envVars, connectionInfo)); - try - { - // Launch the test host. - var hostLaunchedTask = this.testHostManager.LaunchTestHostAsync(testHostStartInfo, this.CancellationTokenSource.Token); - this.testHostLaunched = hostLaunchedTask.Result; - - if (this.testHostLaunched && testHostConnectionInfo.Role == ConnectionRole.Host) - { - // If test runtime is service host, try to poll for connection as client - this.RequestSender.InitializeCommunication(); - } - } - catch (Exception ex) + if (this.testHostLaunched && testHostConnectionInfo.Role == ConnectionRole.Host) { - EqtTrace.Error("ProxyOperationManager: Failed to launch testhost :{0}", ex); - - this.CancellationTokenSource.Token.ThrowTestPlatformExceptionIfCancellationRequested(); - throw new TestPlatformException(string.Format(CultureInfo.CurrentUICulture, CrossPlatEngineResources.FailedToLaunchTestHost, ex.ToString())); + // If test runtime is service host, try to poll for connection as client. + this.RequestSender.InitializeCommunication(); } + } + catch (Exception ex) + { + EqtTrace.Error("ProxyOperationManager: Failed to launch testhost :{0}", ex); - // Warn the user that execution will wait for debugger attach. - var hostDebugEnabled = Environment.GetEnvironmentVariable("VSTEST_HOST_DEBUG"); - var nativeHostDebugEnabled = Environment.GetEnvironmentVariable("VSTEST_HOST_NATIVE_DEBUG"); + this.CancellationTokenSource.Token.ThrowTestPlatformExceptionIfCancellationRequested(); + throw new TestPlatformException(string.Format( + CultureInfo.CurrentUICulture, + CrossPlatEngineResources.FailedToLaunchTestHost, + ex.ToString())); + } - if (!string.IsNullOrEmpty(hostDebugEnabled) && hostDebugEnabled.Equals("1", StringComparison.Ordinal) || - new PlatformEnvironment().OperatingSystem.Equals(PlatformOperatingSystem.Windows) && - !string.IsNullOrEmpty(nativeHostDebugEnabled) && nativeHostDebugEnabled.Equals("1", StringComparison.Ordinal)) - { - ConsoleOutput.Instance.WriteLine(CrossPlatEngineResources.HostDebuggerWarning, OutputLevel.Warning); - ConsoleOutput.Instance.WriteLine( - string.Format("Process Id: {0}, Name: {1}", this.testHostProcessId, this.processHelper.GetProcessName(this.testHostProcessId)), - OutputLevel.Information); + // Warn the user that execution will wait for debugger attach. + var hostDebugEnabled = Environment.GetEnvironmentVariable("VSTEST_HOST_DEBUG"); + var nativeHostDebugEnabled = Environment.GetEnvironmentVariable("VSTEST_HOST_NATIVE_DEBUG"); - // Increase connection timeout when debugging is enabled. - connTimeout *= 5; - } - - // If TestHost does not launch then throw exception - // If Testhost launches, wait for connection. - if (!this.testHostLaunched || - !this.RequestSender.WaitForRequestHandlerConnection(connTimeout * 1000, this.CancellationTokenSource.Token)) - { - EqtTrace.Verbose($"Test host failed to start Test host launched:{testHostLaunched} test host exited: {testHostExited.IsSet}"); - // Throw a test platform exception with the appropriate message if user requested cancellation - this.CancellationTokenSource.Token.ThrowTestPlatformExceptionIfCancellationRequested(); + if (!string.IsNullOrEmpty(hostDebugEnabled) && hostDebugEnabled.Equals("1", StringComparison.Ordinal) || + new PlatformEnvironment().OperatingSystem.Equals(PlatformOperatingSystem.Windows) && + !string.IsNullOrEmpty(nativeHostDebugEnabled) && nativeHostDebugEnabled.Equals("1", StringComparison.Ordinal)) + { + ConsoleOutput.Instance.WriteLine( + CrossPlatEngineResources.HostDebuggerWarning, + OutputLevel.Warning); + + ConsoleOutput.Instance.WriteLine( + string.Format( + "Process Id: {0}, Name: {1}", + this.testHostProcessId, + this.processHelper.GetProcessName(this.testHostProcessId)), + OutputLevel.Information); + + // Increase connection timeout when debugging is enabled. + connTimeout *= 5; + } - // Throw a test platform exception along with the error messages from the test if the test host exited unexpectedly - // before communication was established - this.ThrowOnTestHostExited(this.testHostExited.IsSet); + // If test host does not launch then throw exception, otherwise wait for connection. + if (!this.testHostLaunched || + !this.RequestSender.WaitForRequestHandlerConnection( + connTimeout * 1000, + this.CancellationTokenSource.Token)) + { + EqtTrace.Verbose($"Test host failed to start Test host launched:{testHostLaunched} test host exited: {testHostExited.IsSet}"); + // Throw a test platform exception with the appropriate message if user requested cancellation. + this.CancellationTokenSource.Token.ThrowTestPlatformExceptionIfCancellationRequested(); - // Throw a test platform exception stating the connection to test could not be established even after waiting - // for the configure timeout period - this.ThrowExceptionOnConnectionFailure(connTimeout); - } + // Throw a test platform exception along with the error messages from the test if the test host exited unexpectedly + // before communication was established. + this.ThrowOnTestHostExited(this.testHostExited.IsSet); - // Handling special case for dotnet core projects with older test hosts - // Older test hosts are not aware of protocol version check - // Hence we should not be sending VersionCheck message to these test hosts - this.CompatIssueWithVersionCheckAndRunsettings(); + // Throw a test platform exception stating the connection to test could not be established even after waiting + // for the configure timeout period. + this.ThrowExceptionOnConnectionFailure(connTimeout); + } - if (this.versionCheckRequired) - { - this.RequestSender.CheckVersionWithTestHost(); - } + // Handling special case for dotnet core projects with older test hosts. + // Older test hosts are not aware of protocol version check, hence we should not be + // sending VersionCheck message to these test hosts. + this.CompatIssueWithVersionCheckAndRunsettings(); - this.initialized = true; + if (this.versionCheckRequired) + { + this.RequestSender.CheckVersionWithTestHost(); } + this.initialized = true; + return true; } /// - /// Closes the channel, terminate test host process. + /// Closes the channel and terminates the test host process. /// public virtual void Close() { try { - // do not send message if host did not launch + // Do not send message if the host did not launch. if (this.testHostLaunched) { this.RequestSender.EndSession(); @@ -228,55 +323,50 @@ public virtual void Close() EqtTrace.Warning("ProxyOperationManager: Timed out waiting for test host to exit. Will terminate process."); - // please clean up test host. - this.testHostManager.CleanTestHostAsync(CancellationToken.None).Wait(); + // Please clean up test host. + this.TestHostManager.CleanTestHostAsync(CancellationToken.None).Wait(); - this.testHostManager.HostExited -= this.TestHostManagerHostExited; - this.testHostManager.HostLaunched -= this.TestHostManagerHostLaunched; + this.TestHostManager.HostExited -= this.TestHostManagerHostExited; + this.TestHostManager.HostLaunched -= this.TestHostManagerHostLaunched; } } #endregion /// - /// This method is exposed to enable derived classes to modify TestProcessStartInfo. E.g. DataCollection need additional environment variables to be passed, etc. + /// This method is exposed to enable derived classes to modify + /// . For example, data collectors need additional + /// environment variables to be passed. /// - /// - /// The sources. - /// + /// + /// The test process start info. + /// /// /// The . /// - protected virtual TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) + public virtual TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) { - // Update Telemetry Opt in status because by default in Test Host Telemetry is opted out - var telemetryOptedIn = this.requestData.IsTelemetryOptedIn ? "true" : "false"; - testProcessStartInfo.Arguments += " --telemetryoptedin " + telemetryOptedIn; - return testProcessStartInfo; - } - - protected string GetTimestampedLogFile(string logFile) - { - if (string.IsNullOrWhiteSpace(logFile)) + if (this.baseProxy == null) { - return null; + // Update Telemetry Opt in status because by default in Test Host Telemetry is opted out + var telemetryOptedIn = this.RequestData.IsTelemetryOptedIn ? "true" : "false"; + testProcessStartInfo.Arguments += " --telemetryoptedin " + telemetryOptedIn; + return testProcessStartInfo; } - return Path.ChangeExtension( - logFile, - string.Format( - "host.{0}_{1}{2}", - DateTime.Now.ToString("yy-MM-dd_HH-mm-ss_fffff"), - new PlatformEnvironment().GetCurrentManagedThreadId(), - Path.GetExtension(logFile))).AddDoubleQuote(); + return this.baseProxy.UpdateTestProcessStartInfo(testProcessStartInfo); } /// - /// This function will remove the unknown runsettings node from runsettings for old testhost who throws exception for unknown node. + /// This function will remove the unknown run settings nodes from the run settings strings. + /// This is necessary because older test hosts may throw exceptions when encountering + /// unknown nodes. /// - /// runsettings string - /// runsetting after removing un-required nodes - protected string RemoveNodesFromRunsettingsIfRequired(string runsettingsXml, Action logMessage) + /// + /// Run settings string. + /// + /// The run settings after removing non-required nodes. + public string RemoveNodesFromRunsettingsIfRequired(string runsettingsXml, Action logMessage) { var updatedRunSettingsXml = runsettingsXml; if (!this.makeRunsettingsCompatibleSet) @@ -293,20 +383,36 @@ protected string RemoveNodesFromRunsettingsIfRequired(string runsettingsXml, Act return updatedRunSettingsXml; } + private string GetTimestampedLogFile(string logFile) + { + if (string.IsNullOrWhiteSpace(logFile)) + { + return null; + } + + return Path.ChangeExtension( + logFile, + string.Format( + "host.{0}_{1}{2}", + DateTime.Now.ToString("yy-MM-dd_HH-mm-ss_fffff"), + new PlatformEnvironment().GetCurrentManagedThreadId(), + Path.GetExtension(logFile))).AddDoubleQuote(); + } + private void CompatIssueWithVersionCheckAndRunsettings() { - var properties = this.testHostManager.GetType().GetRuntimeProperties(); + var properties = this.TestHostManager.GetType().GetRuntimeProperties(); var versionCheckProperty = properties.FirstOrDefault(p => string.Equals(p.Name, versionCheckPropertyName, StringComparison.OrdinalIgnoreCase)); if (versionCheckProperty != null) { - this.versionCheckRequired = (bool)versionCheckProperty.GetValue(this.testHostManager); + this.versionCheckRequired = (bool)versionCheckProperty.GetValue(this.TestHostManager); } var makeRunsettingsCompatibleProperty = properties.FirstOrDefault(p => string.Equals(p.Name, makeRunsettingsCompatiblePropertyName, StringComparison.OrdinalIgnoreCase)); if (makeRunsettingsCompatibleProperty != null) { - this.makeRunsettingsCompatible = (bool)makeRunsettingsCompatibleProperty.GetValue(this.testHostManager); + this.makeRunsettingsCompatible = (bool)makeRunsettingsCompatibleProperty.GetValue(this.TestHostManager); this.makeRunsettingsCompatibleSet = true; } } @@ -322,11 +428,11 @@ private void TestHostManagerHostExited(object sender, HostProviderEventArgs e) EqtTrace.Verbose("CrossPlatEngine.TestHostManagerHostExited: calling on client process exit callback."); this.testHostProcessStdError = e.Data; - // this needs to be set before we call the OnClientProcess exit - // because the OnClientProcess will short-circuit WaitForRequestHandlerConnection in SetupChannel - // that then continues to throw an exception and checks if the testhost process exited - // if not it reports timeout, if we don't set this before OnClientProcessExit we will report timeout - // even though we exited the test host before even attempting the connect + // This needs to be set before we call the OnClientProcess exit because the + // OnClientProcess will short-circuit WaitForRequestHandlerConnection in SetupChannel + // that then continues to throw an exception and checks if the test host process exited. + // If not it reports timeout, if we don't set this before OnClientProcessExit we will + // report timeout even though we exited the test host before even attempting the connect. this.testHostExited.Set(); this.RequestSender.OnClientProcessExit(this.testHostProcessStdError); } @@ -335,8 +441,8 @@ private void ThrowOnTestHostExited(bool testHostExited) { if (testHostExited) { - // we might consider passing standard output here in case standard error is not available because some - // errors don't end up in the standard error output + // We might consider passing standard output here in case standard error is not + // available because some errors don't end up in the standard error output. throw new TestPlatformException(string.Format(CrossPlatEngineResources.TestHostExitedWithError, this.testHostProcessStdError)); } } @@ -346,7 +452,7 @@ private void ThrowExceptionOnConnectionFailure(int connTimeout) // Failed to launch testhost process. var errorMsg = CrossPlatEngineResources.InitializationFailed; - // Testhost launched but Timeout occurred due to machine slowness. + // Testhost launched but timeout occurred due to machine slowness. if (this.testHostLaunched) { errorMsg = string.Format( @@ -360,7 +466,7 @@ private void ThrowExceptionOnConnectionFailure(int connTimeout) // After testhost process launched failed with error. if (!string.IsNullOrWhiteSpace(this.testHostProcessStdError)) { - // Testhost failed with error + // Testhost failed with error. errorMsg = string.Format(CrossPlatEngineResources.TestHostExitedWithError, this.testHostProcessStdError); } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManagerWithDataCollection.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManagerWithDataCollection.cs new file mode 100644 index 0000000000..67b8b07c4c --- /dev/null +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManagerWithDataCollection.cs @@ -0,0 +1,146 @@ +// 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.CrossPlatEngine.Client +{ + using System; + using System.Collections.Generic; + + using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; + using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection.Interfaces; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Host; + + /// + /// The proxy operation manager with data collection. + /// + public class ProxyOperationManagerWithDataCollection : ProxyOperationManager + { + private IDictionary dataCollectionEnvironmentVariables; + private IRequestData requestData; + private int dataCollectionPort; + + /// + /// Initializes a new instance of the + /// class. + /// + /// + /// The request data. + /// The request sender. + /// The test host manager. + /// The data collection proxy. + public ProxyOperationManagerWithDataCollection( + IRequestData requestData, + ITestRequestSender requestSender, + ITestRuntimeProvider testHostManager, + IProxyDataCollectionManager proxyDataCollectionManager) + : base( + requestData, + requestSender, + testHostManager) + { + this.ProxyDataCollectionManager = proxyDataCollectionManager; + this.DataCollectionRunEventsHandler = new DataCollectionRunEventsHandler(); + this.requestData = requestData; + this.dataCollectionEnvironmentVariables = new Dictionary(); + + testHostManager.HostLaunched += this.TestHostLaunchedHandler; + } + + /// + public override void Initialize(bool skipDefaultAdapters) + { + this.ProxyDataCollectionManager.Initialize(); + + try + { + var dataCollectionParameters = this.ProxyDataCollectionManager.BeforeTestRunStart( + resetDataCollectors: true, + isRunStartingNow: true, + runEventsHandler: this.DataCollectionRunEventsHandler); + + if (dataCollectionParameters != null) + { + this.dataCollectionEnvironmentVariables = dataCollectionParameters.EnvironmentVariables; + this.dataCollectionPort = dataCollectionParameters.DataCollectionEventsPort; + } + } + catch (Exception) + { + // On failure in calling BeforeTestRunStart, call AfterTestRunEnd to end the data + // collection process. + this.ProxyDataCollectionManager.AfterTestRunEnd( + isCanceled: true, + runEventsHandler: this.DataCollectionRunEventsHandler); + throw; + } + + base.Initialize(skipDefaultAdapters); + } + + /// + public override TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) + { + if (testProcessStartInfo.EnvironmentVariables == null) + { + testProcessStartInfo.EnvironmentVariables = this.dataCollectionEnvironmentVariables; + } + else + { + foreach (var kvp in this.dataCollectionEnvironmentVariables) + { + testProcessStartInfo.EnvironmentVariables[kvp.Key] = kvp.Value; + } + } + + // Update telemetry opt in status because by default test host telemetry is opted out. + var telemetryOptedIn = this.requestData.IsTelemetryOptedIn ? "true" : "false"; + testProcessStartInfo.Arguments += " --datacollectionport " + this.dataCollectionPort + + " --telemetryoptedin " + telemetryOptedIn; + + return testProcessStartInfo; + } + + /// + public override bool SetupChannel( + IEnumerable sources, + string runSettings, + ITestMessageEventHandler eventHandler) + { + // Log all the messages that are reported while initializing the DataCollectionClient. + if (this.DataCollectionRunEventsHandler.Messages.Count > 0) + { + foreach (var message in this.DataCollectionRunEventsHandler.Messages) + { + eventHandler.HandleLogMessage(message.Item1, message.Item2); + } + + this.DataCollectionRunEventsHandler.Messages.Clear(); + } + + return base.SetupChannel(sources, runSettings); + } + + /// + /// Gets the data collection run events handler. + /// + internal DataCollectionRunEventsHandler DataCollectionRunEventsHandler + { + get; private set; + } + + /// + /// Gets the proxy data collection manager. + /// + internal IProxyDataCollectionManager ProxyDataCollectionManager + { + get; private set; + } + + private void TestHostLaunchedHandler(object sender, HostProviderEventArgs e) + { + this.ProxyDataCollectionManager.TestHostLaunched(e.ProcessId); + } + } +} diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs index 89809c139e..50137fe787 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs @@ -24,9 +24,10 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities public class TestRequestHandler : ITestRequestHandler { private int protocolVersion = 1; - - // Also check TestRequestSender. - private int highestSupportedVersion = 4; + + // Must be in sync with the highest supported version in + // src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs file. + private int highestSupportedVersion = 5; private readonly IDataSerializer dataSerializer; private ITestHostManagerFactory testHostManagerFactory; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/Resources.Designer.cs index 683eb49355..8ee4d46c5c 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/Resources.Designer.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/Resources.Designer.cs @@ -11,8 +11,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Resources { using System; using System.Reflection; - - + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -205,6 +204,15 @@ internal static string LaunchDebugProcessNotAllowedForANonDebugRun { } } + /// + /// Looks up a localized string similar to Could not find an available proxy to deque.. + /// + internal static string NoAvailableProxyForDeque { + get { + return ResourceManager.GetString("NoAvailableProxyForDeque", resourceCulture); + } + } + /// /// Looks up a localized string similar to Could not find {0}. Make sure that the dotnet is installed on the machine.. /// @@ -232,6 +240,15 @@ internal static string NonExistingExtensions { } } + /// + /// Looks up a localized string similar to Proxy with id {0} is not managed by the current session manager.. + /// + internal static string NoSuchProxyId { + get { + return ResourceManager.GetString("NoSuchProxyId", resourceCulture); + } + } + /// /// Looks up a localized string similar to No test matches the given testcase filter `{0}` in {1}. /// @@ -259,6 +276,15 @@ internal static string OldTestHostIsGettingUsed { } } + /// + /// Looks up a localized string similar to Proxy with id {0} is already available and cannot be re-enqueued.. + /// + internal static string ProxyIsAlreadyAvailable { + get { + return ResourceManager.GetString("ProxyIsAlreadyAvailable", resourceCulture); + } + } + /// /// Looks up a localized string similar to , . /// diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/Resources.resx b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/Resources.resx index 4ef18b3697..802bf4805b 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/Resources.resx +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/Resources.resx @@ -204,4 +204,13 @@ {0} Access denied while trying to create "TestResults" folder in mentioned location. You are getting this exception because you are running vstest.console.exe from a folder which requires having write access. To solve the issue: please run vstest.console.exe from a folder where you have write privileges. + + Could not find an available proxy to deque. + + + Proxy with id {0} is not managed by the current session manager. + + + Proxy with id {0} is already available and cannot be re-enqueued. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.cs.xlf index b1003dc39a..d4bdceb585 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.cs.xlf @@ -217,6 +217,21 @@ {0} Při pokusu o vytvoření složky TestResults v uvedeném umístění došlo k odepření přístupu. Tato výjimka se vyvolala, protože spouštíte vstest.console.exe ze složky, která vyžaduje, abyste měli přístup pro zápis. Pokud chcete problém vyřešit, spusťte prosím vstest.console.exe ze složky, ve které máte oprávnění k zápisu. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.de.xlf index 6d380d102c..ca3062eaaf 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.de.xlf @@ -217,6 +217,21 @@ {0} Beim Erstellen des Ordners "TestResults" am angegebenen Speicherort wurde der Zugriff verweigert. Sie erhalten diese Ausnahme, weil Sie "vstest.console.exe" in einem Ordner ausführen, für den Schreibzugriff erforderlich ist. So beheben Sie das Problem: Führen Sie "vstest.console.exe" in einem Ordner aus, für den Sie Schreibberechtigungen besitzen. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.es.xlf index b7610805b3..d3db989baf 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.es.xlf @@ -217,6 +217,21 @@ {0} Se denegó el acceso al intentar crear la carpeta "TestResults" en la ubicación mencionada. Está recibiendo esta excepción porque está ejecutando vstest.console.exe desde una carpeta que requiere acceso de escritura. Para solucionar la incidencia: ejecute vstest.console.exe desde una carpeta en la que tenga privilegios de escritura. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.fr.xlf index 82a010bfab..ee72ac5bab 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.fr.xlf @@ -217,6 +217,21 @@ {0} Accès refusé durant la tentative de création du dossier "TestResults" à l'emplacement indiqué. Vous obtenez cette exception, car vous exécutez vstest.console.exe à partir d'un dossier qui nécessite un accès en écriture. Pour résoudre le problème, exécutez vstest.console.exe à partir d'un dossier sur lequel vous disposez de privilèges d'accès en écriture. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.it.xlf index 1df6136b0f..8649118a15 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.it.xlf @@ -217,6 +217,21 @@ {0} Accesso negato durante il tentativo di creare la cartella "TestResults" nel percorso indicato. Si riceve questa eccezione perché si esegue vstest.console.exe da una cartella per cui è necessario l'accesso in scrittura. Per risolvere il problema, eseguire vstest.console.exe da una cartella per cui si hanno privilegi di scrittura. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ja.xlf index 133ec5d7fb..4e662324df 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ja.xlf @@ -217,6 +217,21 @@ {0} 記載した場所に "TestResults" フォルダーを作成しようとしたときにアクセスが拒否されました。書き込みアクセスを必要とするフォルダーから vstest.console.exe を実行しているため、この例外が発生しています。この問題を解決するには、書き込み特権のあるフォルダーから vstest.console.exe を実行してください。 + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ko.xlf index e7fcac9dde..04bcaa7cc2 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ko.xlf @@ -217,6 +217,21 @@ {0} "TestResults" 폴더를 언급된 위치에 만드는 동안 액세스가 거부되었습니다. 쓰기 권한이 필요한 폴더에서 vstest.console.exe를 실행하고 있으므로 이 예외가 발생했습니다. 이 문제를 해결하려면 쓰기 권한이 있는 폴더에서 vstest.console.exe를 실행하세요. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.pl.xlf index 872c937c60..fb53bcdaa9 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.pl.xlf @@ -217,6 +217,21 @@ {0} Odmowa dostępu podczas próby utworzenia folderu „TestResults” w określonej lokalizacji. Widzisz ten wyjątek, ponieważ program vstest.console.exe został uruchomiony z folderu wymagającego dostępu do zapisu. Aby rozwiązać ten problem: uruchom program vstest.console.exe z folderu, w którym masz uprawnienia do zapisu. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.pt-BR.xlf index 3fd80a0374..f47a6d5865 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.pt-BR.xlf @@ -217,6 +217,21 @@ {0} Acesso negado ao tentar criar a pasta "TestResults" no local mencionado. Você está recebendo esta exceção porque está executando o vstest.console.exe em uma pasta que requer acesso para gravação. Para resolver o problema: execute vstest.console.exe em uma pasta na qual você tenha privilégios de gravação. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ru.xlf index 4327825219..1cfbd0091c 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.ru.xlf @@ -217,6 +217,21 @@ {0} Отказано в доступе при попытке создания папки "TestResults" в указанном расположении. Это исключение возникло, так как вы запускаете файл vstest.console.exe из папки, для которой требуется доступ на запись. Чтобы устранить эту проблему, запустите vstest.console.exe из папки, для которой у вас есть разрешения на запись. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.tr.xlf index e232d989cd..8da3d4fd0f 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.tr.xlf @@ -217,6 +217,21 @@ {0} Belirtilen konumda "TestResults" klasörü oluşturulmaya çalışılırken erişim engellendi. Yazma erişimi gerektiren bir klasörden vstest.console.exe çalıştırdığınız için bu özel durumu aldınız. Sorunu çözmek için lütfen yazma ayrıcalıklarına sahip olduğunuz bir klasörden vstest.console.exe dosyasını çalıştırın. + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.xlf index 7c88354463..a5998be2f6 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.xlf @@ -128,6 +128,21 @@ {0} Access denied while trying to create "TestResults" folder in mentioned location. You are getting this exception because you are running vstest.console.exe from a folder which requires having write access. To solve the issue: please run vstest.console.exe from a folder where you have write privileges. For more information, please look at the error message: + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.zh-Hans.xlf index 9404756105..18b16747da 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.zh-Hans.xlf @@ -217,6 +217,21 @@ {0} 尝试在所述位置创建 "TestResults" 文件夹时,访问被拒。你收到此异常是因为你正在从需要具有写入权限的文件夹运行 vstest.console.exe。若要解决此问题,请从你具有写入权限的文件夹运行 vstest.console.exe。 + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.zh-Hant.xlf index da689cb08e..2da2fdd501 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Resources/xlf/Resources.zh-Hant.xlf @@ -217,6 +217,21 @@ {0} 當嘗試在提及的位置上建立 "TestResults" 資料夾時存取被拒。因為您正從需要寫入存取權的資料夾執行 vstest.console.exe,所以收到此例外狀況。若要解決此問題: 請從您有權寫入的資料夾執行 vstest.console.exe。 + + Could not find an available proxy to deque. + Could not find an available proxy to deque. + + + + Proxy with id {0} is not managed by the current session manager. + Proxy with id {0} is not managed by the current session manager. + + + + Proxy with id {0} is already available and cannot be re-enqueued. + Proxy with id {0} is already available and cannot be re-enqueued. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs index 0f9f6e8118..82efbca0be 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs @@ -27,7 +27,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine using Microsoft.VisualStudio.TestPlatform.Utilities; /// - /// Cross Platform test engine entry point for the client. + /// Cross platform test engine entry point for the client. /// public class TestEngine : ITestEngine { @@ -43,7 +43,9 @@ public class TestEngine : ITestEngine { } - protected TestEngine(TestRuntimeProviderManager testHostProviderManager, IProcessHelper processHelper) + protected TestEngine( + TestRuntimeProviderManager testHostProviderManager, + IProcessHelper processHelper) { this.testHostProviderManager = testHostProviderManager; this.processHelper = processHelper; @@ -51,33 +53,28 @@ protected TestEngine(TestRuntimeProviderManager testHostProviderManager, IProces #region ITestEngine implementation - /// - /// Fetches the DiscoveryManager for this engine. This manager would provide all functionality required for discovery. - /// - /// - /// The request data for providing discovery services and data. - /// - /// - /// Test host manager - /// - /// - /// The discovery Criteria. - /// - /// - /// ITestDiscoveryManager object that can do discovery - /// - public IProxyDiscoveryManager GetDiscoveryManager(IRequestData requestData, ITestRuntimeProvider testHostManager, DiscoveryCriteria discoveryCriteria) + /// + public IProxyDiscoveryManager GetDiscoveryManager( + IRequestData requestData, + ITestRuntimeProvider testHostManager, + DiscoveryCriteria discoveryCriteria) { - var parallelLevel = this.VerifyParallelSettingAndCalculateParallelLevel(discoveryCriteria.Sources.Count(), discoveryCriteria.RunSettings); + var parallelLevel = this.VerifyParallelSettingAndCalculateParallelLevel( + discoveryCriteria.Sources.Count(), + discoveryCriteria.RunSettings); - // Collecting IsParallel Enabled - requestData.MetricsCollection.Add(TelemetryDataConstants.ParallelEnabledDuringDiscovery, parallelLevel > 1 ? "True" : "False"); + // Collecting IsParallel enabled. + requestData.MetricsCollection.Add( + TelemetryDataConstants.ParallelEnabledDuringDiscovery, + parallelLevel > 1 ? "True" : "False"); if (this.ShouldRunInNoIsolation(discoveryCriteria.RunSettings, parallelLevel > 1, false)) { var isTelemetryOptedIn = requestData.IsTelemetryOptedIn; var newRequestData = this.GetRequestData(isTelemetryOptedIn); - return new InProcessProxyDiscoveryManager(testHostManager, new TestHostManagerFactory(newRequestData)); + return new InProcessProxyDiscoveryManager( + testHostManager, + new TestHostManagerFactory(newRequestData)); } Func proxyDiscoveryManagerCreator = () => @@ -85,44 +82,82 @@ public IProxyDiscoveryManager GetDiscoveryManager(IRequestData requestData, ITes var hostManager = this.testHostProviderManager.GetTestHostManagerByRunConfiguration(discoveryCriteria.RunSettings); hostManager?.Initialize(TestSessionMessageLogger.Instance, discoveryCriteria.RunSettings); - return new ProxyDiscoveryManager(requestData, new TestRequestSender(requestData.ProtocolConfig, hostManager), hostManager); + return new ProxyDiscoveryManager( + requestData, + new TestRequestSender(requestData.ProtocolConfig, hostManager), + hostManager); }; - return !testHostManager.Shared ? new ParallelProxyDiscoveryManager(requestData, proxyDiscoveryManagerCreator, parallelLevel, sharedHosts: testHostManager.Shared) : proxyDiscoveryManagerCreator(); + return testHostManager.Shared + ? proxyDiscoveryManagerCreator() + : new ParallelProxyDiscoveryManager( + requestData, + proxyDiscoveryManagerCreator, + parallelLevel, + sharedHosts: testHostManager.Shared); } - /// - /// Fetches the ExecutionManager for this engine. This manager would provide all functionality required for execution. - /// - /// The request data for providing execution services and data - /// Test host manager. - /// Test run criterion. - /// - /// ITestExecutionManager object that can do execution - /// - public IProxyExecutionManager GetExecutionManager(IRequestData requestData, ITestRuntimeProvider testHostManager, TestRunCriteria testRunCriteria) + /// + public IProxyExecutionManager GetExecutionManager( + IRequestData requestData, + ITestRuntimeProvider testHostManager, + TestRunCriteria testRunCriteria) { var distinctSources = GetDistinctNumberOfSources(testRunCriteria); - var parallelLevel = this.VerifyParallelSettingAndCalculateParallelLevel(distinctSources, testRunCriteria.TestRunSettings); + var parallelLevel = this.VerifyParallelSettingAndCalculateParallelLevel( + distinctSources, + testRunCriteria.TestRunSettings); - // Collecting IsParallel Enabled - requestData.MetricsCollection.Add(TelemetryDataConstants.ParallelEnabledDuringExecution, parallelLevel > 1 ? "True" : "False"); + // Collecting IsParallel enabled. + requestData.MetricsCollection.Add( + TelemetryDataConstants.ParallelEnabledDuringExecution, + parallelLevel > 1 ? "True" : "False"); var isDataCollectorEnabled = XmlRunSettingsUtilities.IsDataCollectionEnabled(testRunCriteria.TestRunSettings); - var isInProcDataCollectorEnabled = XmlRunSettingsUtilities.IsInProcDataCollectionEnabled(testRunCriteria.TestRunSettings); - if (this.ShouldRunInNoIsolation(testRunCriteria.TestRunSettings, parallelLevel > 1, isDataCollectorEnabled || isInProcDataCollectorEnabled)) + if (this.ShouldRunInNoIsolation( + testRunCriteria.TestRunSettings, + parallelLevel > 1, + isDataCollectorEnabled || isInProcDataCollectorEnabled)) { var isTelemetryOptedIn = requestData.IsTelemetryOptedIn; var newRequestData = this.GetRequestData(isTelemetryOptedIn); - return new InProcessProxyExecutionManager(testHostManager, new TestHostManagerFactory(newRequestData)); + return new InProcessProxyExecutionManager( + testHostManager, + new TestHostManagerFactory(newRequestData)); } - // SetupChannel ProxyExecutionManager with data collection if data collectors are specififed in run settings. + // SetupChannel ProxyExecutionManager with data collection if data collectors are + // specififed in run settings. Func proxyExecutionManagerCreator = () => { - // Create a new HostManager, to be associated with individual ProxyExecutionManager(&POM) + if (testRunCriteria.TestSessionInfo != null) + { + try + { + // In case we have an active test session, data collection needs were + // already taken care of when first creating the session. As a consequence + // we always return this proxy instead of choosing between the vanilla + // execution proxy and the one with data collection enabled. + return new ProxyExecutionManager( + testRunCriteria.TestSessionInfo, + testRunCriteria.DebugEnabledForTestSession); + } + catch (InvalidOperationException ex) + { + // If the proxy creation process based on test session info failed, then + // we'll proceed with the normal creation process as if no test session + // info was passed in in the first place. + // + // WARNING: This should not normally happen and it raises questions + // regarding the test session pool operation and consistency. + EqtTrace.Warning("ProxyExecutionManager failed: {0}", ex.ToString()); + } + } + + // Create a new host manager, to be associated with individual + // ProxyExecutionManager(&POM) var hostManager = this.testHostProviderManager.GetTestHostManagerByRunConfiguration(testRunCriteria.TestRunSettings); hostManager?.Initialize(TestSessionMessageLogger.Instance, testRunCriteria.TestRunSettings); @@ -133,35 +168,97 @@ public IProxyExecutionManager GetExecutionManager(IRequestData requestData, ITes var requestSender = new TestRequestSender(requestData.ProtocolConfig, hostManager); - return isDataCollectorEnabled ? new ProxyExecutionManagerWithDataCollection(requestData, requestSender, hostManager, new ProxyDataCollectionManager(requestData, testRunCriteria.TestRunSettings, GetSourcesFromTestRunCriteria(testRunCriteria))) - : new ProxyExecutionManager(requestData, requestSender, hostManager); + return isDataCollectorEnabled + ? new ProxyExecutionManagerWithDataCollection( + requestData, + requestSender, + hostManager, + new ProxyDataCollectionManager( + requestData, + testRunCriteria.TestRunSettings, + GetSourcesFromTestRunCriteria(testRunCriteria))) + : new ProxyExecutionManager( + requestData, + requestSender, + hostManager); }; // parallelLevel = 1 for desktop should go via else route. - if (parallelLevel > 1 || !testHostManager.Shared) + return (parallelLevel > 1 || !testHostManager.Shared) + ? new ParallelProxyExecutionManager( + requestData, + proxyExecutionManagerCreator, + parallelLevel, + sharedHosts: testHostManager.Shared) + : proxyExecutionManagerCreator(); + } + + /// + public IProxyTestSessionManager GetTestSessionManager( + IRequestData requestData, + ITestRuntimeProvider testHostManager, + StartTestSessionCriteria testSessionCriteria) + { + var parallelLevel = this.VerifyParallelSettingAndCalculateParallelLevel( + testSessionCriteria.Sources.Count, + testSessionCriteria.RunSettings); + + requestData.MetricsCollection.Add( + TelemetryDataConstants.ParallelEnabledDuringStartTestSession, + parallelLevel > 1 ? "True" : "False"); + + var isDataCollectorEnabled = XmlRunSettingsUtilities.IsDataCollectionEnabled(testSessionCriteria.RunSettings); + var isInProcDataCollectorEnabled = XmlRunSettingsUtilities.IsInProcDataCollectionEnabled(testSessionCriteria.RunSettings); + + if (this.ShouldRunInNoIsolation( + testSessionCriteria.RunSettings, + parallelLevel > 1, + isDataCollectorEnabled || isInProcDataCollectorEnabled)) { - return new ParallelProxyExecutionManager(requestData, proxyExecutionManagerCreator, parallelLevel, sharedHosts: testHostManager.Shared); + // This condition is the equivalent of the in-process proxy execution manager case. + // In this case all tests will be run in the vstest.console process, so there's no + // test host to be started. As a consequence there'll be no session info. + return null; } - else + + Func proxyCreator = () => { - return proxyExecutionManagerCreator(); - } + var hostManager = this.testHostProviderManager.GetTestHostManagerByRunConfiguration(testSessionCriteria.RunSettings); + hostManager?.Initialize(TestSessionMessageLogger.Instance, testSessionCriteria.RunSettings); + + if (testSessionCriteria.TestHostLauncher != null) + { + hostManager.SetCustomLauncher(testSessionCriteria.TestHostLauncher); + } + + var requestSender = new TestRequestSender(requestData.ProtocolConfig, hostManager); + + return isDataCollectorEnabled + ? new ProxyOperationManagerWithDataCollection( + requestData, + requestSender, + hostManager, + new ProxyDataCollectionManager( + requestData, + testSessionCriteria.RunSettings, + testSessionCriteria.Sources)) + : new ProxyOperationManager( + requestData, + requestSender, + hostManager); + }; + + return new ProxyTestSessionManager(parallelLevel, proxyCreator); } - /// - /// Fetches the extension manager for this engine. This manager would provide extensibility features that this engine supports. - /// - /// ITestExtensionManager object that helps with extensibility + /// public ITestExtensionManager GetExtensionManager() { - return this.testExtensionManager ?? (this.testExtensionManager = new TestExtensionManager()); + return this.testExtensionManager + ?? (this.testExtensionManager = new TestExtensionManager()); } - /// - /// Fetches the logger manager for this engine. This manager will provide logger extensibility features that this engine supports. - /// - /// The request data for providing common execution services and data - /// ITestLoggerManager object that helps with logger extensibility. + /// public ITestLoggerManager GetLoggerManager(IRequestData requestData) { return new TestLoggerManager( @@ -174,7 +271,8 @@ public ITestLoggerManager GetLoggerManager(IRequestData requestData) private static int GetDistinctNumberOfSources(TestRunCriteria testRunCriteria) { - // No point in creating more processes if number of sources is less than what user configured for + // No point in creating more processes if number of sources is less than what the user + // configured for. int numSources = 1; if (testRunCriteria.HasSpecificTests) { @@ -190,48 +288,56 @@ private static int GetDistinctNumberOfSources(TestRunCriteria testRunCriteria) } /// - /// Verifies Parallel Setting and returns parallel level to use based on the run criteria + /// Verifies parallel setting and returns parallel level to use based on the run criteria. /// - /// - /// The source Count. - /// - /// - /// The run Settings. - /// - /// - /// Parallel Level to use - /// - private int VerifyParallelSettingAndCalculateParallelLevel(int sourceCount, string runSettings) + /// + /// The source count. + /// The run settings. + /// + /// The parallel level to use. + private int VerifyParallelSettingAndCalculateParallelLevel( + int sourceCount, + string runSettings) { - // Default is 1 + // Default is 1. int parallelLevelToUse = 1; try { - // Check the User Parallel Setting + // Check the user parallel setting. int userParallelSetting = RunSettingsUtilities.GetMaxCpuCount(runSettings); - parallelLevelToUse = userParallelSetting == 0 ? Environment.ProcessorCount : userParallelSetting; + parallelLevelToUse = userParallelSetting == 0 + ? Environment.ProcessorCount + : userParallelSetting; var enableParallel = parallelLevelToUse > 1; - EqtTrace.Verbose("TestEngine: Initializing Parallel Execution as MaxCpuCount is set to: {0}", parallelLevelToUse); + EqtTrace.Verbose( + "TestEngine: Initializing Parallel Execution as MaxCpuCount is set to: {0}", + parallelLevelToUse); - // Verify if the number of Sources is less than user setting of parallel - // we should use number of sources as the parallel level, if sources count is less than parallel level + // Verify if the number of sources is less than user setting of parallel. + // We should use number of sources as the parallel level, if sources count is less + // than parallel level. if (enableParallel) { parallelLevelToUse = Math.Min(sourceCount, parallelLevelToUse); - // If only one source, no need to use parallel service client + // If only one source, no need to use parallel service client. enableParallel = parallelLevelToUse > 1; if (EqtTrace.IsInfoEnabled) { - EqtTrace.Verbose("TestEngine: ParallelExecution set to '{0}' as the parallel level is adjusted to '{1}' based on number of sources", enableParallel, parallelLevelToUse); + EqtTrace.Verbose( + "TestEngine: ParallelExecution set to '{0}' as the parallel level is adjusted to '{1}' based on number of sources", + enableParallel, + parallelLevelToUse); } } } catch (Exception ex) { - EqtTrace.Error("TestEngine: Error occurred while initializing ParallelExecution: {0}", ex); + EqtTrace.Error( + "TestEngine: Error occurred while initializing ParallelExecution: {0}", + ex); EqtTrace.Warning("TestEngine: Defaulting to Sequential Execution"); parallelLevelToUse = 1; @@ -240,7 +346,10 @@ private int VerifyParallelSettingAndCalculateParallelLevel(int sourceCount, stri return parallelLevelToUse; } - private bool ShouldRunInNoIsolation(string runsettings, bool isParallelEnabled, bool isDataCollectorEnabled) + private bool ShouldRunInNoIsolation( + string runsettings, + bool isParallelEnabled, + bool isDataCollectorEnabled) { var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettings); @@ -261,7 +370,7 @@ private bool ShouldRunInNoIsolation(string runsettings, bool isParallelEnabled, var currentProcessPath = this.processHelper.GetCurrentProcessFileName(); - // If running with the dotnet executable, then don't run in InProcess + // If running with the dotnet executable, then don't run in in process. if (currentProcessPath.EndsWith("dotnet", StringComparison.OrdinalIgnoreCase) || currentProcessPath.EndsWith("dotnet.exe", StringComparison.OrdinalIgnoreCase)) { @@ -269,12 +378,12 @@ private bool ShouldRunInNoIsolation(string runsettings, bool isParallelEnabled, } // Return true if - // 1) Not running in parallel - // 2) Data collector is not enabled - // 3) Target framework is x86 or anyCpu - // 4) DisableAppDomain is false - // 5) Not running in design mode - // 6) target framework is NETFramework (Desktop test) + // 1) Not running in parallel; + // 2) Data collector is not enabled; + // 3) Target framework is x86 or anyCpu; + // 4) DisableAppDomain is false; + // 5) Not running in design mode; + // 6) target framework is NETFramework (Desktop test); if (!isParallelEnabled && !isDataCollectorEnabled && (runConfiguration.TargetPlatform == Architecture.X86 || runConfiguration.TargetPlatform == Architecture.AnyCPU) && @@ -293,28 +402,33 @@ private bool ShouldRunInNoIsolation(string runsettings, bool isParallelEnabled, } /// - /// Get Request Data on basis of Telemetry OptedIn or not + /// Get request data on basis of telemetry opted in or not. /// - /// - /// + /// + /// A flag indicating if telemetry is opted in. + /// + /// The request data. private IRequestData GetRequestData(bool isTelemetryOptedIn) { return new RequestData - { - MetricsCollection = isTelemetryOptedIn - ? (IMetricsCollection)new MetricsCollection() - : new NoOpMetricsCollection(), - IsTelemetryOptedIn = isTelemetryOptedIn - }; + { + MetricsCollection = isTelemetryOptedIn + ? (IMetricsCollection)new MetricsCollection() + : new NoOpMetricsCollection(), + IsTelemetryOptedIn = isTelemetryOptedIn + }; } /// - /// Gets test sources from test run criteria + /// Gets test sources from test run criteria. /// - /// test sources + /// + /// The test sources. private IEnumerable GetSourcesFromTestRunCriteria(TestRunCriteria testRunCriteria) { - return testRunCriteria.HasSpecificTests ? TestSourcesUtility.GetSources(testRunCriteria.Tests) : testRunCriteria.Sources; + return testRunCriteria.HasSpecificTests + ? TestSourcesUtility.GetSources(testRunCriteria.Tests) + : testRunCriteria.Sources; } } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/TestSession/ProxyTestSessionManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/TestSession/ProxyTestSessionManager.cs new file mode 100644 index 0000000000..1d072944fc --- /dev/null +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/TestSession/ProxyTestSessionManager.cs @@ -0,0 +1,218 @@ +// 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.CrossPlatEngine +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Threading.Tasks; + + using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; + + using CrossPlatResources = Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Resources.Resources; + + /// + /// Orchestrates test session operations for the engine communicating with the client. + /// + public class ProxyTestSessionManager : IProxyTestSessionManager + { + private readonly object lockObject = new object(); + private int parallelLevel; + private bool skipDefaultAdapters; + private Func proxyCreator; + private Queue availableProxyQueue; + private IDictionary proxyMap; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The parallel level. + /// The proxy creator. + public ProxyTestSessionManager(int parallelLevel, Func proxyCreator) + { + this.parallelLevel = parallelLevel; + this.proxyCreator = proxyCreator; + + this.availableProxyQueue = new Queue(); + this.proxyMap = new Dictionary(); + } + + /// + public void Initialize(bool skipDefaultAdapters) + { + this.skipDefaultAdapters = skipDefaultAdapters; + } + + /// + public void StartSession( + StartTestSessionCriteria criteria, + ITestSessionEventsHandler eventsHandler) + { + var testSessionInfo = new TestSessionInfo(); + Task[] taskList = new Task[this.parallelLevel]; + + // Create all the proxies in parallel, one task per proxy. + for (int i = 0; i < this.parallelLevel; ++i) + { + taskList[i] = Task.Factory.StartNew(() => + { + // Create the proxy. + var operationManagerProxy = this.CreateProxy(); + + // Initialize the proxy. + operationManagerProxy.Initialize(this.skipDefaultAdapters); + + // Start the test host associated to the proxy. + operationManagerProxy.SetupChannel( + criteria.Sources, + criteria.RunSettings, + eventsHandler); + }); + } + + // Wait for proxy creation to be over. + Task.WaitAll(taskList); + + // Make the session available. + TestSessionPool.Instance.AddSession(testSessionInfo, this); + + // Let the caller know the session has been created. + eventsHandler.HandleStartTestSessionComplete(testSessionInfo); + } + + /// + public void StopSession() + { + // TODO (copoiena): Do nothing for now because in the current implementation the + // testhosts are disposed of right after the test run is done. However, when we'll + // decide to re-use the testhosts for discovery & execution we'll perform some + // changes for keeping them alive indefinetely, so the responsability for killing + // testhosts will be with the users of the vstest.console wrapper. Then we'll need + // to be able to dispose of the testhosts here. + + // foreach (var kvp in this.proxyMap) + // { + // } + } + + /// + /// Dequeues a proxy to be used either by discovery or execution. + /// + /// + /// The dequeued proxy. + public ProxyOperationManager DequeueProxy() + { + ProxyOperationManagerContainer proxyContainer = null; + + lock (this.lockObject) + { + // No proxy available means the caller will have to create its own proxy. + if (this.availableProxyQueue.Count == 0) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.CurrentUICulture, + CrossPlatResources.NoAvailableProxyForDeque)); + } + + // Get the proxy id from the available queue. + var proxyId = this.availableProxyQueue.Dequeue(); + + // Get the actual proxy. + proxyContainer = this.proxyMap[proxyId]; + + // Mark the proxy as unavailable. + proxyContainer.IsAvailable = false; + } + + return proxyContainer.Proxy; + } + + /// + /// Enqueues a proxy back once discovery or executions is done with it. + /// + /// + /// The id of the proxy to be re-enqueued. + public void EnqueueProxy(Guid proxyId) + { + lock (this.lockObject) + { + // Check if the proxy exists. + if (!this.proxyMap.ContainsKey(proxyId)) + { + throw new ArgumentException( + string.Format( + CultureInfo.CurrentUICulture, + CrossPlatResources.NoSuchProxyId, + proxyId)); + } + + // Get the actual proxy. + var proxyContainer = this.proxyMap[proxyId]; + if (proxyContainer.IsAvailable) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.CurrentUICulture, + CrossPlatResources.ProxyIsAlreadyAvailable, + proxyId)); + } + + // Mark the proxy as available. + proxyContainer.IsAvailable = true; + + // Re-enqueue the proxy in the available queue. + this.availableProxyQueue.Enqueue(proxyId); + } + } + + private ProxyOperationManager CreateProxy() + { + // Invoke the proxy creator. + var proxy = this.proxyCreator(); + + lock (this.lockObject) + { + // Add the proxy to the map. + this.proxyMap.Add(proxy.Id, new ProxyOperationManagerContainer(proxy, available: true)); + + // Enqueue the proxy id in the available queue. + this.availableProxyQueue.Enqueue(proxy.Id); + } + + return proxy; + } + } + + /// + /// Defines a container encapsulating the proxy and its corresponding state info. + /// + internal class ProxyOperationManagerContainer + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The proxy. + /// A flag indicating if the proxy is available to do work. + public ProxyOperationManagerContainer(ProxyOperationManager proxy, bool available) + { + this.Proxy = proxy; + this.IsAvailable = available; + } + + /// + /// Gets or sets the proxy. + /// + public ProxyOperationManager Proxy { get; set; } + + /// + /// Gets or sets a flag indicating if the proxy is available to do work. + /// + public bool IsAvailable { get; set; } + } +} diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/TestSession/TestSessionPool.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/TestSession/TestSessionPool.cs new file mode 100644 index 0000000000..5110552b50 --- /dev/null +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/TestSession/TestSessionPool.cs @@ -0,0 +1,167 @@ +// 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.CrossPlatEngine +{ + using System; + using System.Collections.Generic; + + using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + + /// + /// Represents the test session pool. + /// + public class TestSessionPool + { + private static object instanceLockObject = new object(); + private static volatile TestSessionPool instance; + + private object lockObject = new object(); + private Dictionary sessionPool; + + /// + /// Initializes a new instance of the class. + /// + private TestSessionPool() + { + this.sessionPool = new Dictionary(); + } + + /// + /// Gets the test session pool instance. + /// + /// + /// Thread-safe singleton pattern. + public static TestSessionPool Instance + { + get + { + if (instance == null) + { + lock (instanceLockObject) + { + if (instance == null) + { + instance = new TestSessionPool(); + } + } + } + + return instance; + } + } + + /// + /// Adds a session to the pool. + /// + /// + /// The test session info object. + /// The proxy manager object. + /// + /// True if the operation succeeded, false otherwise. + public bool AddSession( + TestSessionInfo testSessionInfo, + ProxyTestSessionManager proxyManager) + { + lock (this.lockObject) + { + // Check if the session info already exists. + if (this.sessionPool.ContainsKey(testSessionInfo)) + { + return false; + } + + // Adds an association between session info and proxy manager to the pool. + this.sessionPool.Add(testSessionInfo, proxyManager); + return true; + } + } + + /// + /// Kills and removes a session from the pool. + /// + /// + /// The test session info object. + /// + /// True if the operation succeeded, false otherwise. + public bool KillSession(TestSessionInfo testSessionInfo) + { + // TODO (copoiena): What happens if some request is running for the current session ? + // Should we stop the request as well ? Probably yes. + ProxyTestSessionManager proxyManager = null; + + lock (this.lockObject) + { + // Check if the session info exists. + if (!this.sessionPool.ContainsKey(testSessionInfo)) + { + return false; + } + + // Remove the session from the pool. + proxyManager = this.sessionPool[testSessionInfo]; + this.sessionPool.Remove(testSessionInfo); + } + + // Kill the session. + proxyManager.StopSession(); + return true; + } + + /// + /// Gets a reference to the proxy object from the session pool. + /// + /// + /// The test session info object. + /// + /// The proxy object. + public ProxyOperationManager TakeProxy(TestSessionInfo testSessionInfo) + { + ProxyTestSessionManager sessionManager = null; + lock (this.lockObject) + { + // Gets the session manager reference from the pool. + sessionManager = this.sessionPool[testSessionInfo]; + } + + // Deque an actual proxy to do work. + // + // This can potentially throw, but let the caller handle this as it must recover from + // this error by creating its own proxy. + return sessionManager.DequeueProxy(); + } + + /// + /// Returns the proxy object to the session pool. + /// + /// + /// The test session info object. + /// The proxy id to be returned. + public void ReturnProxy(TestSessionInfo testSessionInfo, Guid proxyId) + { + ProxyTestSessionManager sessionManager = null; + lock (this.lockObject) + { + // Gets the session manager reference from the pool. + sessionManager = this.sessionPool[testSessionInfo]; + } + + try + { + // Try re-enqueueing the specified proxy. + sessionManager.EnqueueProxy(proxyId); + } + catch (InvalidOperationException ex) + { + // If we are unable to re-enqueue the proxy we just eat up the exception here as + // it is safe to proceed. + // + // WARNING: This should not normally happen and it raises questions regarding the + // test session pool operation and consistency. + EqtTrace.Warning("TestSessionPool.ReturnProxy failed: {0}", ex.ToString()); + } + } + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IBaseProxy.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IBaseProxy.cs new file mode 100644 index 0000000000..838f6d8807 --- /dev/null +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IBaseProxy.cs @@ -0,0 +1,20 @@ +// 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.ObjectModel.Client +{ + /// + /// Provides basic functionality for the Proxy Operation Manager. + /// + public interface IBaseProxy + { + /// + /// Updates the test process start info. + /// + /// + /// The test process start info to be updated. + /// + /// The updated test process start info. + TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo); + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestPlatform.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestPlatform.cs index 9dbf71b13c..a842484b04 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestPlatform.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestPlatform.cs @@ -6,39 +6,71 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Client using System; using System.Collections.Generic; + /// + /// Defines the functionality of the test platform. + /// public interface ITestPlatform : IDisposable { /// - /// Update the extensions to be used by the test service + /// Updates the extensions to be used by the test service. /// + /// /// - /// Specifies the path to unit test extensions. - /// If no additional extension is available, then specify null or empty list. + /// Specifies the path to unit test extensions. If no additional extension is available, + /// then specify null or empty list. /// - /// - void UpdateExtensions(IEnumerable pathToAdditionalExtensions, bool skipExtensionFilters); + /// + /// Flag indicating if we should skip the default adapters initialization. + /// + void UpdateExtensions( + IEnumerable pathToAdditionalExtensions, + bool skipExtensionFilters); /// - /// Clear the extensions + /// Clears the extensions. /// void ClearExtensions(); /// - /// Creates a discovery request + /// Creates a discovery request. /// - /// Providing common services and data for Discovery - /// Specifies the discovery parameters + /// + /// Providing common services and data for discovery. + /// Specifies the discovery parameters. /// Test platform options. - /// DiscoveryRequest object - IDiscoveryRequest CreateDiscoveryRequest(IRequestData requestData, DiscoveryCriteria discoveryCriteria, TestPlatformOptions options); + /// + /// A DiscoveryRequest object. + IDiscoveryRequest CreateDiscoveryRequest( + IRequestData requestData, + DiscoveryCriteria discoveryCriteria, + TestPlatformOptions options); /// /// Creates a test run request. /// - /// Providing common services and data for Execution - /// Specifies the test run criteria + /// + /// Providing common services and data for execution. + /// Specifies the test run criteria. /// Test platform options. - /// RunRequest object - ITestRunRequest CreateTestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteria, TestPlatformOptions options); + /// + /// A RunRequest object. + ITestRunRequest CreateTestRunRequest( + IRequestData requestData, + TestRunCriteria testRunCriteria, + TestPlatformOptions options); + + /// + /// Starts a test session. + /// + /// + /// + /// Providing common services and data for test session start. + /// + /// Specifies the start test session criteria. + /// Events handler for handling session events. + void StartTestSession( + IRequestData requestData, + StartTestSessionCriteria criteria, + ITestSessionEventsHandler eventsHandler); } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestRunEventsHandler.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestRunEventsHandler.cs index 171da88e2a..ecd37b85c7 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestRunEventsHandler.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestRunEventsHandler.cs @@ -36,7 +36,7 @@ public interface ITestRunEventsHandler : ITestMessageEventHandler } /// - /// Interface for handling generic message events during test discovery or execution + /// Interface for handling generic message events during various operations /// public interface ITestMessageEventHandler { diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestSessionEventsHandler.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestSessionEventsHandler.cs new file mode 100644 index 0000000000..fc3dea783a --- /dev/null +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestSessionEventsHandler.cs @@ -0,0 +1,30 @@ +// 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.ObjectModel.Client +{ + /// + /// Interface contract for handling test session events. + /// + public interface ITestSessionEventsHandler : ITestMessageEventHandler + { + /// + /// Dispatch StartTestSession complete event to listeners. + /// + /// + /// The test session info. + void HandleStartTestSessionComplete(TestSessionInfo testSessionInfo); + + /// + /// Dispatch StopTestSession complete event to listeners. + /// + /// + /// + /// The test session info for the session that was stopped. + /// + /// + /// True if the session was successfully stopped, false otherwise. + /// + void HandleStopTestSessionComplete(TestSessionInfo testSessionInfo, bool stopped); + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StartTestSessionAckPayload.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StartTestSessionAckPayload.cs new file mode 100644 index 0000000000..5ec1bc5c79 --- /dev/null +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StartTestSessionAckPayload.cs @@ -0,0 +1,20 @@ +// 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.ObjectModel.Client.Payloads +{ + using System.Runtime.Serialization; + + /// + /// Class used to define the start test session ack payload sent by the design mode client + /// back to the vstest.console translation layers. + /// + public class StartTestSessionAckPayload + { + /// + /// Gets or sets the test session info. + /// + [DataMember] + public TestSessionInfo TestSessionInfo { get; set; } + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StartTestSessionPayload.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StartTestSessionPayload.cs new file mode 100644 index 0000000000..cf25fe44a7 --- /dev/null +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StartTestSessionPayload.cs @@ -0,0 +1,45 @@ +// 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.ObjectModel.Client.Payloads +{ + using System.Collections.Generic; + using System.Runtime.Serialization; + + /// + /// Class used to define the start test session payload sent by the vstest.console translation + /// layers into design mode. + /// + public class StartTestSessionPayload + { + /// + /// Gets or sets the sources used for starting the test session. + /// + [DataMember] + public IList Sources { get; set; } + + /// + /// Gets or sets the run settings used for starting the test session. + /// + [DataMember] + public string RunSettings { get; set; } + + /// + /// Gets or sets a flag indicating if debugging is enabled. + /// + [DataMember] + public bool IsDebuggingEnabled { get; set; } + + /// + /// Gets or sets a flag indicating if a custom host launcher should be used. + /// + [DataMember] + public bool HasCustomHostLauncher { get; set; } + + /// + /// Gets or sets the test platform options. + /// + [DataMember] + public TestPlatformOptions TestPlatformOptions { get; set; } + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StopTestSessionAckPayload.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StopTestSessionAckPayload.cs new file mode 100644 index 0000000000..ecca18eafd --- /dev/null +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/StopTestSessionAckPayload.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 Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads +{ + using System.Runtime.Serialization; + + /// + /// Class used to define the stop test session ack payload sent by the design mode client + /// back to the vstest.console translation layers. + /// + public class StopTestSessionAckPayload + { + /// + /// Gets or sets the test session info. + /// + [DataMember] + public TestSessionInfo TestSessionInfo { get; set; } + + /// + /// Gets or sets a value indicating if the session was successfully stopped or not. + /// + [DataMember] + public bool IsStopped { get; set; } + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/TestRunRequestPayload.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/TestRunRequestPayload.cs index 8851fdec14..2c37f3e086 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/TestRunRequestPayload.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/TestRunRequestPayload.cs @@ -53,10 +53,12 @@ public class TestRunRequestPayload /// Gets or sets the testplatform options /// [DataMember] - public TestPlatformOptions TestPlatformOptions - { - get; - set; - } + public TestPlatformOptions TestPlatformOptions { get; set; } + + /// + /// Gets or sets the test session info. + /// + [DataMember] + public TestSessionInfo TestSessionInfo { get; set; } } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/StartTestSessionCriteria.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/StartTestSessionCriteria.cs new file mode 100644 index 0000000000..9970b20d5f --- /dev/null +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/StartTestSessionCriteria.cs @@ -0,0 +1,34 @@ +// 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.ObjectModel.Client +{ + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + using System.Collections.Generic; + using System.Runtime.Serialization; + + /// + /// Class used to define the start test session criteria. + /// + [DataContract] + public class StartTestSessionCriteria + { + /// + /// Gets or sets the sources used for starting the test session. + /// + [DataMember] + public IList Sources { get; set; } + + /// + /// Gets or sets the run settings used for starting the test session. + /// + [DataMember] + public string RunSettings { get; set; } + + /// + /// Gets or sets the test host launcher used for starting the test session. + /// + [DataMember] + public ITestHostLauncher TestHostLauncher { get; set; } + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/TestPlatformOptions.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/TestPlatformOptions.cs index f00c8cb3e4..ea7597419e 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/TestPlatformOptions.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/TestPlatformOptions.cs @@ -14,6 +14,7 @@ public class TestPlatformOptions /// /// Gets or sets the filter criteria for test cases. /// + /// /// /// This is only used when running tests with sources. /// @@ -23,6 +24,7 @@ public class TestPlatformOptions /// /// Gets or sets the filter options if there are any. /// + /// /// /// This will be valid only if TestCase filter is present. /// @@ -30,13 +32,13 @@ public class TestPlatformOptions public FilterOptions FilterOptions { get; set; } /// - /// Gets or sets whether Metrics should be collected or not. + /// Gets or sets whether metrics should be collected or not. /// [DataMember] public bool CollectMetrics { get; set; } /// - /// Gets or sets whether default adapters should be skipped or not. + /// Gets or sets whether default adapters should be skipped or not. /// [DataMember] public bool SkipDefaultAdapters { get; set; } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/TestRunCriteria.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/TestRunCriteria.cs index 10e739f382..d92536d314 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/TestRunCriteria.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/TestRunCriteria.cs @@ -14,7 +14,7 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Client using Microsoft.VisualStudio.TestPlatform.ObjectModel.Resources; /// - /// Defines the testRun criterion + /// Defines the test run criterion. /// public class TestRunCriteria : BaseTestRunCriteria, ITestRunConfiguration { @@ -24,92 +24,103 @@ public class TestRunCriteria : BaseTestRunCriteria, ITestRunConfiguration /// /// Initializes a new instance of the class. /// - /// - /// Sources which contains tests that should be executed - /// - /// - /// Frequency of run stats event - /// - public TestRunCriteria(IEnumerable sources, long frequencyOfRunStatsChangeEvent) - : this(sources, frequencyOfRunStatsChangeEvent, true) + /// + /// Sources which contains tests that should be executed. + /// Frequency of run stats event. + public TestRunCriteria( + IEnumerable sources, + long frequencyOfRunStatsChangeEvent) + : this( + sources, + frequencyOfRunStatsChangeEvent, + true) { } /// /// Initializes a new instance of the class. /// - /// - /// Sources which contains tests that should be executed - /// - /// - /// Frequency of run stats event - /// + /// + /// Sources which contains tests that should be executed. + /// Frequency of run stats event. /// /// Whether the execution process should be kept alive after the run is finished or not. /// - public TestRunCriteria(IEnumerable sources, long frequencyOfRunStatsChangeEvent, bool keepAlive) - : this(sources, frequencyOfRunStatsChangeEvent, keepAlive, string.Empty) + public TestRunCriteria( + IEnumerable sources, + long frequencyOfRunStatsChangeEvent, + bool keepAlive) + : this( + sources, + frequencyOfRunStatsChangeEvent, + keepAlive, + string.Empty) { } /// /// Initializes a new instance of the class. /// - /// - /// Sources which contains tests that should be executed - /// - /// - /// Frequency of run stats event - /// + /// + /// Sources which contains tests that should be executed. + /// Frequency of run stats event. /// /// Whether the execution process should be kept alive after the run is finished or not. /// - /// - /// Settings used for this run. - /// - public TestRunCriteria(IEnumerable sources, long frequencyOfRunStatsChangeEvent, bool keepAlive, string testSettings) - : this(sources, frequencyOfRunStatsChangeEvent, keepAlive, testSettings, TimeSpan.MaxValue) + /// Settings used for this run. + public TestRunCriteria( + IEnumerable sources, + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings) + : this( + sources, + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + TimeSpan.MaxValue) { } /// /// Initializes a new instance of the class. /// - /// - /// Sources which contains tests that should be executed - /// - /// - /// Frequency of run stats event - /// + /// + /// Sources which contains tests that should be executed. + /// Frequency of run stats event. /// /// Whether the execution process should be kept alive after the run is finished or not. /// - /// - /// The test Settings. - /// + /// Settings used for this run. /// /// Timeout that triggers sending results regardless of cache size. /// - public TestRunCriteria(IEnumerable sources, long frequencyOfRunStatsChangeEvent, bool keepAlive, string testSettings, TimeSpan runStatsChangeEventTimeout) - : this(sources, frequencyOfRunStatsChangeEvent, keepAlive, testSettings, runStatsChangeEventTimeout, null) + public TestRunCriteria( + IEnumerable sources, + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings, + TimeSpan runStatsChangeEventTimeout) + : this( + sources, + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + null) { } /// /// Initializes a new instance of the class. /// - /// - /// Sources which contains tests that should be executed - /// - /// - /// Frequency of run stats event - /// + /// + /// Sources which contains tests that should be executed. + /// Frequency of run stats event. /// /// Whether the execution process should be kept alive after the run is finished or not. /// - /// - /// Settings used for this run. - /// + /// Settings used for this run. /// /// Timeout that triggers sending results regardless of cache size. /// @@ -123,36 +134,80 @@ public TestRunCriteria( string testSettings, TimeSpan runStatsChangeEventTimeout, ITestHostLauncher testHostLauncher) - : this(sources, frequencyOfRunStatsChangeEvent, keepAlive, testSettings, runStatsChangeEventTimeout, testHostLauncher, null, null) + : this( + sources, + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + testHostLauncher, + null, + null) { } /// /// Initializes a new instance of the class. /// - /// - /// Sources which contains tests that should be executed + /// + /// Sources which contains tests that should be executed. + /// Frequency of run stats event. + /// + /// Whether the execution process should be kept alive after the run is finished or not. /// - /// - /// Frequency of run stats event + /// Settings used for this run. + /// + /// Timeout that triggers sending results regardless of cache size. /// + /// + /// Test host launcher. If null then default will be used. + /// + /// Test case filter. + /// Filter options. + public TestRunCriteria( + IEnumerable sources, + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings, + TimeSpan runStatsChangeEventTimeout, + ITestHostLauncher testHostLauncher, + string testCaseFilter, + FilterOptions filterOptions) + : this( + sources, + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + testHostLauncher, + testCaseFilter, + filterOptions, + testSessionInfo: null, + debugEnabledForTestSession: false) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// Sources which contains tests that should be executed. + /// Frequency of run stats event. /// /// Whether the execution process should be kept alive after the run is finished or not. /// - /// - /// Settings used for this run. - /// + /// Settings used for this run. /// /// Timeout that triggers sending results regardless of cache size. /// /// /// Test host launcher. If null then default will be used. /// - /// - /// Test case filter. - /// - /// - /// Filter options. + /// Test case filter. + /// Filter options. + /// The test session info object. + /// + /// Indicates if debugging should be enabled when we have test session info available. /// public TestRunCriteria( IEnumerable sources, @@ -162,8 +217,15 @@ public TestRunCriteria( TimeSpan runStatsChangeEventTimeout, ITestHostLauncher testHostLauncher, string testCaseFilter, - FilterOptions filterOptions) - : base(frequencyOfRunStatsChangeEvent, keepAlive, testSettings, runStatsChangeEventTimeout, testHostLauncher) + FilterOptions filterOptions, + TestSessionInfo testSessionInfo, + bool debugEnabledForTestSession) + : base( + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + testHostLauncher) { var testSources = sources as IList ?? sources.ToList(); ValidateArg.NotNullOrEmpty(testSources, "sources"); @@ -173,19 +235,21 @@ public TestRunCriteria( this.TestCaseFilter = testCaseFilter; this.FilterOptions = filterOptions; + + this.TestSessionInfo = testSessionInfo; + this.DebugEnabledForTestSession = debugEnabledForTestSession; } /// /// Initializes a new instance of the class. - /// Create the TestRunCriteria for a test run + /// Create the TestRunCriteria for a test run. /// - /// - /// Sources which contains tests that should be executed - /// - /// - /// The TestRunCriteria - /// - public TestRunCriteria(IEnumerable sources, TestRunCriteria testRunCriteria) + /// + /// Sources which contains tests that should be executed. + /// The test run criteria. + public TestRunCriteria( + IEnumerable sources, + TestRunCriteria testRunCriteria) : base(testRunCriteria) { var testSources = sources as IList ?? sources.ToArray(); @@ -202,18 +266,15 @@ public TestRunCriteria(IEnumerable sources, TestRunCriteria testRunCrite /// /// Initializes a new instance of the class. /// + /// /// - /// Sources which contains tests that should be executed - /// - /// - /// Frequency of run stats event + /// Sources which contains tests that should be executed. /// + /// Frequency of run stats event. /// /// Whether the execution process should be kept alive after the run is finished or not. /// - /// - /// Settings used for this run. - /// + /// Settings used for this run. /// /// Timeout that triggers sending results regardless of cache size. /// @@ -227,7 +288,12 @@ public TestRunCriteria( string testSettings, TimeSpan runStatsChangeEventTimeout, ITestHostLauncher testHostLauncher) - : base(frequencyOfRunStatsChangeEvent, keepAlive, testSettings, runStatsChangeEventTimeout, testHostLauncher) + : base( + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + testHostLauncher) { ValidateArg.NotNullOrEmpty(adapterSourceMap, "adapterSourceMap"); @@ -237,86 +303,99 @@ public TestRunCriteria( /// /// Initializes a new instance of the class. /// - /// - /// Tests which should be executed - /// - /// - /// Frequency of run stats event - /// - public TestRunCriteria(IEnumerable tests, long frequencyOfRunStatsChangeEvent) - : this(tests, frequencyOfRunStatsChangeEvent, false) + /// + /// Tests which should be executed. + /// Frequency of run stats event. + public TestRunCriteria( + IEnumerable tests, + long frequencyOfRunStatsChangeEvent) + : this( + tests, + frequencyOfRunStatsChangeEvent, + false) { } /// /// Initializes a new instance of the class. /// - /// - /// Tests which should be executed - /// - /// - /// Frequency of run stats event - /// + /// + /// Tests which should be executed. + /// Frequency of run stats event. /// - /// Whether or not to keep the test executor process alive after run completion + /// Whether or not to keep the test executor process alive after run completion. /// - public TestRunCriteria(IEnumerable tests, long frequencyOfRunStatsChangeEvent, bool keepAlive) - : this(tests, frequencyOfRunStatsChangeEvent, keepAlive, string.Empty) + public TestRunCriteria( + IEnumerable tests, + long frequencyOfRunStatsChangeEvent, + bool keepAlive) + : this( + tests, + frequencyOfRunStatsChangeEvent, + keepAlive, + string.Empty) { } /// /// Initializes a new instance of the class. /// - /// - /// Tests which should be executed - /// - /// - /// Frequency of run stats event - /// + /// + /// Tests which should be executed. + /// Frequency of run stats event. /// - /// Whether or not to keep the test executor process alive after run completion + /// Whether or not to keep the test executor process alive after run completion. /// - /// - /// Settings used for this run. - /// - public TestRunCriteria(IEnumerable tests, long frequencyOfRunStatsChangeEvent, bool keepAlive, string testSettings) - : this(tests, frequencyOfRunStatsChangeEvent, keepAlive, testSettings, TimeSpan.MaxValue) + /// Settings used for this run. + public TestRunCriteria( + IEnumerable tests, + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings) + : this( + tests, + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + TimeSpan.MaxValue) { } /// /// Initializes a new instance of the class. /// - /// - /// Tests which should be executed - /// - /// - /// Frequency of run stats event - /// + /// + /// Tests which should be executed. + /// Frequency of run stats event. /// - /// Whether or not to keep the test executor process alive after run completion - /// - /// - /// Settings used for this run. + /// Whether or not to keep the test executor process alive after run completion. /// + /// Settings used for this run. /// /// Timeout that triggers sending results regardless of cache size. /// - public TestRunCriteria(IEnumerable tests, long frequencyOfRunStatsChangeEvent, bool keepAlive, string testSettings, TimeSpan runStatsChangeEventTimeout) - : this(tests, frequencyOfRunStatsChangeEvent, keepAlive, testSettings, runStatsChangeEventTimeout, null) + public TestRunCriteria( + IEnumerable tests, + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings, + TimeSpan runStatsChangeEventTimeout) + : this( + tests, + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + null) { } /// /// Initializes a new instance of the class. /// - /// - /// Tests which should be executed - /// - /// - /// The BaseTestRunCriteria - /// + /// + /// Tests which should be executed. + /// The base test run criteria. public TestRunCriteria(IEnumerable tests, BaseTestRunCriteria baseTestRunCriteria) : base(baseTestRunCriteria) { @@ -329,35 +408,84 @@ public TestRunCriteria(IEnumerable tests, BaseTestRunCriteria baseTest /// /// Initializes a new instance of the class. /// - /// - /// Sources which contains tests that should be executed + /// + /// Tests which should be executed. + /// Frequency of run stats event. + /// + /// Whether or not to keep the test executor process alive after run completion. /// - /// - /// Frequency of run stats event + /// Settings used for this run. + /// + /// Timeout that triggers sending results regardless of cache size. /// - /// - /// Whether or not to keep the test executor process alive after run completion + /// + /// Test host launcher. If null then default will be used. /// - /// - /// Settings used for this run. + public TestRunCriteria( + IEnumerable tests, + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings, + TimeSpan runStatsChangeEventTimeout, + ITestHostLauncher testHostLauncher) + : this( + tests, + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + testHostLauncher, + testSessionInfo: null, + debugEnabledForTestSession: false) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// Tests which should be executed. + /// Frequency of run stats event. + /// + /// Whether or not to keep the test executor process alive after run completion. /// + /// Settings used for this run. /// /// Timeout that triggers sending results regardless of cache size. /// /// /// Test host launcher. If null then default will be used. /// - public TestRunCriteria(IEnumerable tests, long frequencyOfRunStatsChangeEvent, bool keepAlive, string testSettings, TimeSpan runStatsChangeEventTimeout, ITestHostLauncher testHostLauncher) - : base(frequencyOfRunStatsChangeEvent, keepAlive, testSettings, runStatsChangeEventTimeout, testHostLauncher) + /// The test session info object. + /// + /// Indicates if debugging should be enabled when we have test session info available. + /// + public TestRunCriteria( + IEnumerable tests, + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings, + TimeSpan runStatsChangeEventTimeout, + ITestHostLauncher testHostLauncher, + TestSessionInfo testSessionInfo, + bool debugEnabledForTestSession) + : base( + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + testHostLauncher) { var testCases = tests as IList ?? tests.ToList(); ValidateArg.NotNullOrEmpty(testCases, "tests"); this.Tests = testCases; + this.TestSessionInfo = testSessionInfo; + this.DebugEnabledForTestSession = debugEnabledForTestSession; } /// - /// Gets the test Containers (e.g. DLL/EXE/artifacts to scan). + /// Gets the test containers (e.g. DLL/EXE/artifacts to scan). /// [IgnoreDataMember] public IEnumerable Sources @@ -365,7 +493,9 @@ public IEnumerable Sources get { IEnumerable sources = new List(); - return this.AdapterSourceMap?.Values.Aggregate(sources, (current, enumerable) => current.Concat(enumerable)); + return this.AdapterSourceMap?.Values?.Aggregate( + sources, + (current, enumerable) => current.Concat(enumerable)); } } @@ -380,7 +510,7 @@ public IEnumerable Sources /// /// Gets the tests that need to executed in this test run. - /// This will be null if test run is created with specific test containers + /// This will be null if test run is created with specific test containers. /// [DataMember] public IEnumerable Tests { get; private set; } @@ -409,7 +539,7 @@ private set } /// - /// Gets or sets the filter options + /// Gets or sets the filter options. /// /// This is only applicable when TestCaseFilter is present. [DataMember] @@ -431,6 +561,17 @@ private set } } + /// + /// Gets or sets the test session info object. + /// + public TestSessionInfo TestSessionInfo { get; set; } + + /// + /// Gets or sets a flag indicating if debugging should be enabled when we have test session + /// info available. + /// + public bool DebugEnabledForTestSession { get; set; } + /// /// Gets a value indicating whether run criteria is based on specific tests. /// @@ -509,16 +650,15 @@ public override int GetHashCode() } /// - /// Defines the base testRun criterion + /// Defines the base test run criterion. /// public class BaseTestRunCriteria { /// /// Initializes a new instance of the class. /// - /// - /// Run criteria to clone. - /// + /// + /// Run criteria to clone. public BaseTestRunCriteria(BaseTestRunCriteria runCriteria) { ValidateArg.NotNull(runCriteria, "runCriteria"); @@ -533,6 +673,7 @@ public BaseTestRunCriteria(BaseTestRunCriteria runCriteria) /// /// Initializes a new instance of the class. /// + /// /// /// Frequency of TestRunChangedEvent. /// @@ -544,6 +685,7 @@ public BaseTestRunCriteria(long frequencyOfRunStatsChangeEvent) /// /// Initializes a new instance of the class. /// + /// /// /// Frequency of TestRunChangedEvent. /// @@ -558,68 +700,88 @@ public BaseTestRunCriteria(long frequencyOfRunStatsChangeEvent, bool keepAlive) /// /// Initializes a new instance of the class. /// + /// /// /// Frequency of TestRunChangedEvent. /// /// /// Specify if the test host process should be stay alive after run. /// - /// - /// Test run settings. - /// - public BaseTestRunCriteria(long frequencyOfRunStatsChangeEvent, bool keepAlive, string testSettings) - : this(frequencyOfRunStatsChangeEvent, keepAlive, testSettings, TimeSpan.MaxValue) + /// Test run settings. + public BaseTestRunCriteria( + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings) + : this( + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + TimeSpan.MaxValue) { } /// /// Initializes a new instance of the class. /// + /// /// /// Frequency of TestRunChangedEvent. /// /// /// Specify if the test host process should be stay alive after run. /// - /// - /// Test run settings. - /// + /// Test run settings. /// /// Timeout for a TestRunChangedEvent. /// - public BaseTestRunCriteria(long frequencyOfRunStatsChangeEvent, bool keepAlive, string testSettings, TimeSpan runStatsChangeEventTimeout) - : this(frequencyOfRunStatsChangeEvent, keepAlive, testSettings, runStatsChangeEventTimeout, null) + public BaseTestRunCriteria( + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings, + TimeSpan runStatsChangeEventTimeout) + : this( + frequencyOfRunStatsChangeEvent, + keepAlive, + testSettings, + runStatsChangeEventTimeout, + null) { } /// /// Initializes a new instance of the class. /// + /// /// /// Frequency of TestRunChangedEvent. /// /// /// Specify if the test host process should be stay alive after run. /// - /// - /// Test run settings. - /// + /// Test run settings. /// /// Timeout for a TestRunChangedEvent. /// - /// - /// Test host launcher. - /// - public BaseTestRunCriteria(long frequencyOfRunStatsChangeEvent, bool keepAlive, string testSettings, TimeSpan runStatsChangeEventTimeout, ITestHostLauncher testHostLauncher) + /// Test host launcher. + public BaseTestRunCriteria( + long frequencyOfRunStatsChangeEvent, + bool keepAlive, + string testSettings, + TimeSpan runStatsChangeEventTimeout, + ITestHostLauncher testHostLauncher) { if (frequencyOfRunStatsChangeEvent <= 0) { - throw new ArgumentOutOfRangeException(nameof(frequencyOfRunStatsChangeEvent), Resources.NotificationFrequencyIsNotPositive); + throw new ArgumentOutOfRangeException( + nameof(frequencyOfRunStatsChangeEvent), + Resources.NotificationFrequencyIsNotPositive); } if (runStatsChangeEventTimeout <= TimeSpan.MinValue) { - throw new ArgumentOutOfRangeException(nameof(runStatsChangeEventTimeout), Resources.NotificationTimeoutIsZero); + throw new ArgumentOutOfRangeException( + nameof(runStatsChangeEventTimeout), + Resources.NotificationTimeoutIsZero); } this.FrequencyOfRunStatsChangeEvent = frequencyOfRunStatsChangeEvent; @@ -630,7 +792,8 @@ public BaseTestRunCriteria(long frequencyOfRunStatsChangeEvent, bool keepAlive, } /// - /// Gets a value indicating whether the test executor process should remain alive after run completion. + /// Gets a value indicating whether the test executor process should remain alive after + /// run completion. /// [DataMember] public bool KeepAlive { get; private set; } @@ -650,6 +813,7 @@ public BaseTestRunCriteria(long frequencyOfRunStatsChangeEvent, bool keepAlive, /// /// Gets the frequency of run stats test event. /// + /// /// /// Run stats change event will be raised after completion of these number of tests. /// Note that this event is raised asynchronously and the underlying execution process is not diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/TestSessionInfo.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/TestSessionInfo.cs new file mode 100644 index 0000000000..21ce34307b --- /dev/null +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/TestSessionInfo.cs @@ -0,0 +1,64 @@ +// 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.ObjectModel.Client +{ + using System; + using System.Runtime.Serialization; + + /// + /// Defines the test session info object to be passed around between vstest.console and + /// vstest.console wrapper in order to indentify the current session. + /// + [DataContract] + public class TestSessionInfo : IEquatable + { + /// + /// Creates an instance of the current class. + /// + public TestSessionInfo() + { + this.Id = Guid.NewGuid(); + } + + /// + /// Gets the session id. + /// + [DataMember] + public Guid Id { get; private set; } + + /// + /// Calculates the hash code for the current object. + /// + /// + /// An integer representing the computed hashcode value. + public override int GetHashCode() + { + return this.Id.GetHashCode(); + } + + /// + /// Checks if the specified object is equal to the current instance. + /// + /// + /// The object to be checked. + /// + /// True if the two objects are equal, false otherwise. + public override bool Equals(object obj) + { + return this.Equals(obj as TestSessionInfo); + } + + /// + /// Checks if the specified session is equal to the current instance. + /// + /// + /// The session to be checked. + /// + /// True if the two sessions are equal, false otherwise. + public bool Equals(TestSessionInfo other) + { + return other != null && this.Id == other.Id; + } + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Constants.cs b/src/Microsoft.TestPlatform.ObjectModel/Constants.cs index 9252657190..8a209fb9ad 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Constants.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Constants.cs @@ -168,7 +168,7 @@ public static class Constants /// /// The default protocol version /// - public static readonly ProtocolConfig DefaultProtocolConfig = new ProtocolConfig { Version = 4 }; + public static readonly ProtocolConfig DefaultProtocolConfig = new ProtocolConfig { Version = 5 }; /// /// The minimum protocol version that has debug support diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs index db60124fd1..08d071ac84 100644 --- a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs +++ b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DefaultTestHostManager.cs @@ -404,7 +404,14 @@ private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToke { EqtTrace.Verbose("DefaultTestHostManager: Starting process '{0}' with command line '{1}'", testHostStartInfo.FileName, testHostStartInfo.Arguments); cancellationToken.ThrowIfCancellationRequested(); - this.testHostProcess = this.processHelper.LaunchProcess(testHostStartInfo.FileName, testHostStartInfo.Arguments, testHostStartInfo.WorkingDirectory, testHostStartInfo.EnvironmentVariables, this.ErrorReceivedCallback, this.ExitCallBack, null) as Process; + this.testHostProcess = this.processHelper.LaunchProcess( + testHostStartInfo.FileName, + testHostStartInfo.Arguments, + testHostStartInfo.WorkingDirectory, + testHostStartInfo.EnvironmentVariables, + this.ErrorReceivedCallback, + this.ExitCallBack, + null) as Process; } else { diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs index eb4149d6b0..63971107a6 100644 --- a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs +++ b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs @@ -425,7 +425,14 @@ private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToke EqtTrace.Verbose("DotnetTestHostManager: Starting process '{0}' with command line '{1}'", testHostStartInfo.FileName, testHostStartInfo.Arguments); cancellationToken.ThrowIfCancellationRequested(); - this.testHostProcess = this.processHelper.LaunchProcess(testHostStartInfo.FileName, testHostStartInfo.Arguments, testHostStartInfo.WorkingDirectory, testHostStartInfo.EnvironmentVariables, this.ErrorReceivedCallback, this.ExitCallBack, null) as Process; + this.testHostProcess = this.processHelper.LaunchProcess( + testHostStartInfo.FileName, + testHostStartInfo.Arguments, + testHostStartInfo.WorkingDirectory, + testHostStartInfo.EnvironmentVariables, + this.ErrorReceivedCallback, + this.ExitCallBack, + null) as Process; } else { diff --git a/src/Microsoft.TestPlatform.Utilities/InferRunSettingsHelper.cs b/src/Microsoft.TestPlatform.Utilities/InferRunSettingsHelper.cs index c0edcb8f3f..d9b2ea23be 100644 --- a/src/Microsoft.TestPlatform.Utilities/InferRunSettingsHelper.cs +++ b/src/Microsoft.TestPlatform.Utilities/InferRunSettingsHelper.cs @@ -230,7 +230,7 @@ public static void UpdateTargetFramework(XmlDocument runSettingsDocument, string /// /// RunSettings used for the run /// True if an incompatible collector is found - public static bool AreRunSettingsCollectorsInCompatibleWithTestSettings(string runsettings) + public static bool AreRunSettingsCollectorsIncompatibleWithTestSettings(string runsettings) { // If there's no embedded testsettings.. bail out if (!IsTestSettingsEnabled(runsettings)) diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITestSession.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITestSession.cs new file mode 100644 index 0000000000..206c3aa009 --- /dev/null +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITestSession.cs @@ -0,0 +1,180 @@ +// 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.VsTestConsole.TranslationLayer.Interfaces +{ + using System.Collections.Generic; + + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + + /// + /// Defines a test session that can be used to make calls to the vstest.console + /// process. + /// + public interface ITestSession : ITestSessionAsync + { + /// + /// Starts test discovery. + /// + /// + /// The list of source assemblies for the discovery. + /// The run settings for the discovery. + /// The discovery event handler. + void DiscoverTests( + IEnumerable sources, + string discoverySettings, + ITestDiscoveryEventsHandler discoveryEventsHandler); + + /// + /// Starts test discovery. + /// + /// + /// The list of source assemblies for the discovery. + /// The run settings for the discovery. + /// The test platform options. + /// The discovery event handler. + void DiscoverTests( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler); + + /// + /// Cancels the last discovery request. + /// + new void CancelDiscovery(); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The run event handler. + void RunTests( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + void RunTests( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The run event handler. + void RunTests( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + void RunTests( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Stops the test session. + /// + /// + /// The session event handler. + /// + /// True if the session was successfuly stopped, false otherwise. + bool StopTestSession(ITestSessionEventsHandler eventsHandler); + + /// + /// Cancels the last test run. + /// + new void CancelTestRun(); + + /// + /// Aborts the last test run. + /// + new void AbortTestRun(); + } +} diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITestSessionAsync.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITestSessionAsync.cs new file mode 100644 index 0000000000..9c2aff1496 --- /dev/null +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITestSessionAsync.cs @@ -0,0 +1,182 @@ +// 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.VsTestConsole.TranslationLayer.Interfaces +{ + using System.Collections.Generic; + using System.Threading.Tasks; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + + /// + /// Defines a test session that can be used to make async calls to the vstest.console + /// process. + /// + public interface ITestSessionAsync + { + /// + /// Starts test discovery. + /// + /// + /// The list of source assemblies for the discovery. + /// The run settings for the discovery. + /// The discovery event handler. + /// + Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + ITestDiscoveryEventsHandler discoveryEventsHandler); + + /// + /// Starts test discovery. + /// + /// + /// The list of source assemblies for the discovery. + /// The run settings for the discovery. + /// The test platform options. + /// The discovery event handler. + Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler); + + /// + /// Cancels the last discovery request. + /// + void CancelDiscovery(); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The run event handler. + Task RunTestsAsync( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + Task RunTestsAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The run event handler. + Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The run event handler. + /// The custom host launcher. + Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + /// The custom host launcher. + Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The run event handler. + /// The custom host launcher. + Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + /// The custom host launcher. + Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Stops the test session. + /// + /// + /// The session event handler. + /// + /// True if the session was successfuly stopped, false otherwise. + Task StopTestSessionAsync( + ITestSessionEventsHandler eventsHandler); + + /// + /// Cancels the last test run. + /// + void CancelTestRun(); + + /// + /// Aborts the last test run. + /// + void AbortTestRun(); + } +} diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs index 35e50a9b10..6d016e2b18 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs @@ -5,8 +5,6 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces { using System; using System.Collections.Generic; - using System.Threading; - using System.Threading.Tasks; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; @@ -17,98 +15,165 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces internal interface ITranslationLayerRequestSender : IDisposable, ITranslationLayerRequestSenderAsync { /// - /// Initializes the communication for sending requests + /// Initializes communication with the vstest.console.exe process. + /// Hosts a communication channel and asynchronously connects to vstest.console.exe. /// - /// Port Number of the communication channel + /// + /// Port number of the hosted server on this side. int InitializeCommunication(); /// - /// Waits for Request Handler to be connected + /// Waits for the request handler to be connected. /// - /// Time to wait for connection - /// True, if Handler is connected + /// + /// Time to wait for connection. + /// + /// True if the handler has connected, false otherwise. bool WaitForRequestHandlerConnection(int connectionTimeout); /// - /// Close the Sender + /// Closes the sender. /// void Close(); /// - /// Initializes the Extensions while probing additional extension paths + /// Initializes the extensions while probing additional extension paths. /// - /// Paths to check for additional extensions + /// + /// Paths to check for additional extensions. void InitializeExtensions(IEnumerable pathToAdditionalExtensions); /// /// Discovers the tests /// - /// Sources for discovering tests - /// Run settings for discovering tests - /// Options to be passed into the platform - /// EventHandler for discovery events - void DiscoverTests(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler); + /// + /// Sources for discovering tests. + /// Run settings for discovering tests. + /// Options to be passed into the platform. + /// Event handler for discovery events. + void DiscoverTests( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler); /// - /// Starts the TestRun with given sources and criteria + /// Starts the test run with given sources and criteria. /// - /// Sources for test run - /// RunSettings for test run - /// Options to be passed into the platform - /// EventHandler for test run events - void StartTestRun(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler); + /// + /// Sources for test run. + /// Run settings for test run. + /// Options to be passed into the platform. + /// Test session info. + /// Event handler for test run events. + void StartTestRun( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler); /// - /// Starts the TestRun with given test cases and criteria + /// Starts the test run with given sources and criteria. /// - /// TestCases to run - /// RunSettings for test run - /// Options to be passed into the platform - /// EventHandler for test run events - void StartTestRun(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler); + /// + /// Test cases to run. + /// Run settings for test run. + /// Options to be passed into the platform. + /// Test session info. + /// Event handler for test run events. + void StartTestRun( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler); /// - /// Starts the TestRun with given sources and criteria with custom test host + /// Starts the test run with given sources and criteria and a custom launcher. /// - /// Sources for test run - /// RunSettings for test run - /// Options to be passed into the platform - /// EventHandler for test run events - /// Custom TestHost launcher - void StartTestRunWithCustomHost(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customTestHostLauncher); + /// + /// Sources for test run. + /// Run settings for test run. + /// Options to be passed into the platform. + /// Test session info. + /// Event handler for test run events. + /// Custom test host launcher. + void StartTestRunWithCustomHost( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Starts the TestRun with given test cases and criteria with custom test host + /// Starts the test run with given sources and criteria and a custom launcher. /// - /// TestCases to run - /// RunSettings for test run + /// + /// Test cases to run. + /// Run settings for test run. /// Options to be passed into the platform. - /// EventHandler for test run events - /// Custom TestHost launcher - void StartTestRunWithCustomHost(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customTestHostLauncher); + /// Test session info. + /// Event handler for test run events. + /// Custom test host launcher. + void StartTestRunWithCustomHost( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a new test session. + /// + /// + /// Sources for test run. + /// Run settings for test run. + /// Options to be passed into the platform. + /// Event handler for test session events. + /// Custom test host launcher. + /// + TestSessionInfo StartTestSession( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler, + ITestHostLauncher testHostLauncher); + + /// + /// Stops the test session. + /// + /// + /// Test session info. + /// Event handler for test session events. + bool StopTestSession( + TestSessionInfo testSessionInfo, + ITestSessionEventsHandler eventsHandler); /// - /// Ends the Session + /// Ends the session. /// void EndSession(); /// - /// Cancel the test run + /// Cancels the test run. /// void CancelTestRun(); /// - /// Abort the test run + /// Aborts the test run. /// void AbortTestRun(); /// - /// On process exit unblocks communication waiting calls + /// On process exit unblocks communication waiting calls. /// void OnProcessExited(); /// - /// Cancels the discovery of tests + /// Cancels the discovery of tests. /// void CancelDiscovery(); } diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs index 23166126d7..563eaea1b6 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs @@ -18,43 +18,130 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces internal interface ITranslationLayerRequestSenderAsync : IDisposable { /// - /// Asynchronous equivalent of - /// and . + /// Asynchronous equivalent of + /// and . /// Task InitializeCommunicationAsync(int clientConnectionTimeout); /// /// Asynchronous equivalent of ITranslationLayerRequestSender.DiscoverTests/>. /// - Task DiscoverTestsAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler); + Task DiscoverTestsAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task StartTestRunAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler); + Task StartTestRunAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task StartTestRunAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler); + Task StartTestRunAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task StartTestRunWithCustomHostAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customTestHostLauncher); + Task StartTestRunWithCustomHostAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task StartTestRunWithCustomHostAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customTestHostLauncher); + Task StartTestRunWithCustomHostAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Provides back all attachments to TestPlatform for additional processing (for example merging) + /// Asynchronous equivalent of . /// - /// Collection of attachments - /// Enables metrics collection - /// Events handler - /// Cancellation token - Task ProcessTestRunAttachmentsAsync(IEnumerable attachments, bool collectMetrics, ITestRunAttachmentsProcessingEventsHandler testRunAttachmentsProcessingCompleteEventsHandler, CancellationToken cancellationToken); + Task StartTestSessionAsync( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler, + ITestHostLauncher testHostLauncher); + + /// + /// Asynchronous equivalent of . + /// + Task StopTestSessionAsync( + TestSessionInfo testSessionInfo, + ITestSessionEventsHandler eventsHandler); + + /// + /// Provides back all attachments to test platform for additional processing (for example + /// merging). + /// + /// + /// Collection of attachments. + /// Enables metrics collection. + /// Events handler. + /// Cancellation token. + Task ProcessTestRunAttachmentsAsync( + IEnumerable attachments, + bool collectMetrics, + ITestRunAttachmentsProcessingEventsHandler testRunAttachmentsProcessingCompleteEventsHandler, + CancellationToken cancellationToken); } } diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs index 79e09b98dd..d3ea821e1e 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs @@ -7,6 +7,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + using Microsoft.VisualStudio.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; /// /// Controller for various test operations on the test runner. @@ -19,27 +20,54 @@ public interface IVsTestConsoleWrapper : IVsTestConsoleWrapperAsync void StartSession(); /// - /// Initialize the TestPlatform with Paths to extensions like adapters, loggers and any other extensions + /// Initializes the test platform with paths to extensions like adapters, loggers and any + /// other extensions. /// - /// Full Paths to extension DLLs + /// + /// Full paths to extension DLLs. void InitializeExtensions(IEnumerable pathToAdditionalExtensions); /// - /// Start Discover Tests for the given sources and discovery settings. + /// Starts test discovery. /// - /// List of source assemblies, files to discover tests - /// Settings XML for test discovery - /// EventHandler to receive discovery events - void DiscoverTests(IEnumerable sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler); + /// + /// The list of source assemblies for the discovery. + /// The run settings for the discovery. + /// The discovery event handler. + void DiscoverTests( + IEnumerable sources, + string discoverySettings, + ITestDiscoveryEventsHandler discoveryEventsHandler); /// - /// Start Discover Tests for the given sources and discovery settings. + /// Starts test discovery. /// - /// List of source assemblies, files to discover tests - /// Settings XML for test discovery - /// Options to be passed into the platform. - /// EventHandler to receive discovery events - void DiscoverTests(IEnumerable sources, string discoverySettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler); + /// + /// The list of source assemblies for the discovery. + /// The run settings for the discovery. + /// The test platform options. + /// The discovery event handler. + void DiscoverTests( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler); + + /// + /// Starts test discovery. + /// + /// + /// The list of source assemblies for the discovery. + /// The run settings for the discovery. + /// The test platform options. + /// The test session info object. + /// The discovery event handler. + void DiscoverTests( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestDiscoveryEventsHandler2 discoveryEventsHandler); /// /// Cancels the last discovery request. @@ -47,84 +75,252 @@ public interface IVsTestConsoleWrapper : IVsTestConsoleWrapperAsync new void CancelDiscovery(); /// - /// Starts a test run given a list of sources. + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The run event handler. + void RunTests( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + void RunTests( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The test session info object. + /// The run event handler. + void RunTests( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The run event handler. + void RunTests( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + void RunTests( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The test platform options. + /// The test session info object. + /// The run event handler. + void RunTests( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a test run. + /// + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Starts a test run. /// - /// Sources to Run tests on - /// RunSettings XML to run the tests - /// EventHandler to receive test run events - void RunTests(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler); + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The test session info object. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Starts a test run given a list of sources. + /// Starts a test run. /// - /// Sources to Run tests on - /// RunSettings XML to run the tests - /// Options to be passed into the platform. - /// EventHandler to receive test run events - void RunTests(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler); + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Starts a test run given a list of test cases + /// Starts a test run. /// - /// TestCases to run - /// RunSettings XML to run the tests - /// EventHandler to receive test run events - void RunTests(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler); + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The test platform options. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Starts a test run given a list of test cases + /// Starts a test run. /// - /// TestCases to run - /// RunSettings XML to run the tests - /// Options to be passed into the platform. - /// EventHandler to receive test run events - void RunTests(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler); + /// + /// The list of test cases for the test run. + /// The run settings for the run. + /// The test platform options. + /// The test session info object. + /// The run event handler. + /// The custom host launcher. + void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Starts a test run given a list of sources by giving caller an option to start their own test host. + /// Starts a new test session. /// - /// Sources to Run tests on - /// RunSettings XML to run the tests - /// EventHandler to receive test run events - /// Custom test host launcher for the run. - void RunTestsWithCustomTestHost(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The session event handler. + /// + /// A test session info object. + ITestSession StartTestSession( + IList sources, + string runSettings, + ITestSessionEventsHandler eventsHandler); /// - /// Starts a test run given a list of sources by giving caller an option to start their own test host. + /// Starts a new test session. /// - /// Sources to Run tests on - /// RunSettings XML to run the tests - /// Options to be passed into the platform. - /// EventHandler to receive test run events - /// Custom test host launcher for the run. - void RunTestsWithCustomTestHost(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The session event handler. + /// + /// A test session info object. + ITestSession StartTestSession( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler); /// - /// Starts a test run given a list of test cases by giving caller an option to start their own test host + /// Starts a new test session. /// - /// TestCases to run. - /// RunSettings XML to run the tests. - /// EventHandler to receive test run events. - /// Custom test host launcher for the run. - void RunTestsWithCustomTestHost(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + /// + /// The list of source assemblies for the test run. + /// The run settings for the run. + /// The test platform options. + /// The session event handler. + /// The custom host launcher. + /// + /// A test session info object. + ITestSession StartTestSession( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler, + ITestHostLauncher testHostLauncher); /// - /// Starts a test run given a list of test cases by giving caller an option to start their own test host + /// Stops the test session. /// - /// TestCases to run. - /// RunSettings XML to run the tests. - /// Options to be passed into the platform. - /// EventHandler to receive test run events. - /// Custom test host launcher for the run. - void RunTestsWithCustomTestHost(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + /// + /// The test session info object. + /// The session event handler. + /// + /// True if the session was successfuly stopped, false otherwise. + bool StopTestSession( + TestSessionInfo testSessionInfo, + ITestSessionEventsHandler eventsHandler); /// - /// Cancel the last test run. + /// Cancels the last test run. /// new void CancelTestRun(); /// - /// Abort the last test run. + /// Aborts the last test run. /// new void AbortTestRun(); diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs index 452de38cb6..136e6eec84 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs @@ -10,32 +10,66 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + using Microsoft.VisualStudio.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; /// - /// Asynchronous equivalent of + /// Asynchronous equivalent of . /// public interface IVsTestConsoleWrapperAsync { /// /// Asynchronous equivalent of . /// - /// Task StartSessionAsync(); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// Task InitializeExtensionsAsync(IEnumerable pathToAdditionalExtensions); /// - /// Asynchronous equivalent of + /// Asynchronous equivalent of . /// - Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler); + Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + ITestDiscoveryEventsHandler discoveryEventsHandler); /// - /// Asynchronous equivalent of + /// Asynchronous equivalent of . /// - Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler); + Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler); + + /// + /// Asynchronous equivalent of . + /// + Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestDiscoveryEventsHandler2 discoveryEventsHandler); /// /// See . @@ -43,44 +77,236 @@ public interface IVsTestConsoleWrapperAsync void CancelDiscovery(); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . + /// + Task RunTestsAsync( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Asynchronous equivalent of . + /// + Task RunTestsAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Asynchronous equivalent of . + /// + Task RunTestsAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Asynchronous equivalent of . + /// + Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Asynchronous equivalent of . + /// + Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Asynchronous equivalent of . + /// + Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler); + + /// + /// Asynchronous equivalent of . + /// + Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Asynchronous equivalent of . + /// + Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); + + /// + /// Asynchronous equivalent of . /// - Task RunTestsAsync(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler); + Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task RunTestsAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler); + Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task RunTestsAsync(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler); + Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task RunTestsAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler); + Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task RunTestsWithCustomTestHostAsync(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + Task StartTestSessionAsync( + IList sources, + string runSettings, + ITestSessionEventsHandler eventsHandler); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task RunTestsWithCustomTestHostAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + Task StartTestSessionAsync( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + Task StartTestSessionAsync( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler, + ITestHostLauncher testHostLauncher); /// - /// Asynchronous equivalent of . + /// Asynchronous equivalent of . /// - Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + Task StopTestSessionAsync( + TestSessionInfo testSessionInfo, + ITestSessionEventsHandler eventsHandler); /// /// See . @@ -93,15 +319,24 @@ public interface IVsTestConsoleWrapperAsync void AbortTestRun(); /// - /// Provides back all attachments to TestPlatform for additional processing (for example merging) + /// Gets back all attachments to test platform for additional processing (for example merging). /// - /// Collection of attachments - /// XML processing settings - /// Indicates that all test executions are done and all data is provided - /// Enables metrics collection (used for telemetry) - /// EventHandler to receive session complete event - /// Cancellation token - Task ProcessTestRunAttachmentsAsync(IEnumerable attachments, string processingSettings, bool isLastBatch, bool collectMetrics, ITestRunAttachmentsProcessingEventsHandler eventsHandler, CancellationToken cancellationToken); + /// + /// Collection of attachments. + /// XML processing settings. + /// + /// Indicates that all test executions are done and all data is provided. + /// + /// Enables metrics collection (used for telemetry). + /// Event handler to receive session complete event. + /// Cancellation token. + Task ProcessTestRunAttachmentsAsync( + IEnumerable attachments, + string processingSettings, + bool isLastBatch, + bool collectMetrics, + ITestRunAttachmentsProcessingEventsHandler eventsHandler, + CancellationToken cancellationToken); /// /// See . diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/Resources.Designer.cs index a218efe7f5..222fa23065 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/Resources.Designer.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/Resources.Designer.cs @@ -61,6 +61,24 @@ internal Resources() { } } + /// + /// Looks up a localized string similar to The Start Test Session operation was aborted.. + /// + public static string AbortedStartTestSession { + get { + return ResourceManager.GetString("AbortedStartTestSession", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Stop Test Session operation was aborted.. + /// + public static string AbortedStopTestSession { + get { + return ResourceManager.GetString("AbortedStopTestSession", resourceCulture); + } + } + /// /// Looks up a localized string similar to The active Test Run Attachments Processing was aborted.. /// diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/Resources.resx b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/Resources.resx index eb053d0a74..5a6313b3fd 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/Resources.resx +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/Resources.resx @@ -117,6 +117,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + The Start Test Session operation was aborted. + + + The Stop Test Session operation was aborted. + The active Test Run Attachments Processing was aborted. diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.cs.xlf index ef6c350d70..95c0c9b236 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.cs.xlf @@ -66,6 +66,16 @@ Aktivní zpracovávání příloh testovacího běhu se přerušilo. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.de.xlf index 1f11facce4..7f4b29eb53 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.de.xlf @@ -66,6 +66,16 @@ Die Verarbeitung aktiver Testlaufanlagen wurde abgebrochen. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.es.xlf index 3dede43545..f89b1ed295 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.es.xlf @@ -66,6 +66,16 @@ Se ha anulado el procesamiento de los datos adjuntos de la serie de pruebas activa. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.fr.xlf index 680a7ada9c..1fceea7402 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.fr.xlf @@ -66,6 +66,16 @@ Le traitement des pièces jointes de série de tests actif a été abandonné. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.it.xlf index 2717c36e76..c64f59a677 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.it.xlf @@ -66,6 +66,16 @@ L'elaborazione degli allegati dell'esecuzione dei test attiva è stata interrotta. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ja.xlf index 2b1038749d..bc03ae8885 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ja.xlf @@ -66,6 +66,16 @@ アクティブなテストの実行の添付ファイルの処理が中止されました。 + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ko.xlf index 96d741d53b..1234bc3cb1 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ko.xlf @@ -66,6 +66,16 @@ 활성 테스트 실행 첨부 파일 처리가 중단되었습니다. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.pl.xlf index 30d7fa4159..c119c09142 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.pl.xlf @@ -66,6 +66,16 @@ Aktywne przetwarzanie załączników przebiegu testu zostało przerwane. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.pt-BR.xlf index eb1e8071d1..58d5ee9777 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.pt-BR.xlf @@ -66,6 +66,16 @@ O Processamento de Anexos de Execução de Teste ativo foi anulado. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ru.xlf index 08f0624c16..c7bb3ca803 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.ru.xlf @@ -66,6 +66,16 @@ Обработка вложений активного тестового запуска прервана. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.tr.xlf index 30dd1c7f21..5f79eda7f7 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.tr.xlf @@ -66,6 +66,16 @@ Etkin Test Çalıştırması Ekleri İşlemi durduruldu. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.xlf index 7c79b0d188..4aca1abbc0 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.xlf @@ -28,6 +28,16 @@ The active Test Run Attachments Processing was aborted. + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.zh-Hans.xlf index 980fae06e9..0afc4a6e1b 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.zh-Hans.xlf @@ -66,6 +66,16 @@ 已中止正在进行的测试运行附件处理操作。 + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.zh-Hant.xlf index c0859e0181..0bc7a58b53 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Resources/xlf/Resources.zh-Hant.xlf @@ -66,6 +66,16 @@ 執行中的測試回合附件處理已中止。 + + The Start Test Session operation was aborted. + The Start Test Session operation was aborted. + + + + The Stop Test Session operation was aborted. + The Stop Test Session operation was aborted. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/TestSession.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/TestSession.cs new file mode 100644 index 0000000000..d97761a4c9 --- /dev/null +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/TestSession.cs @@ -0,0 +1,373 @@ +// 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.VsTestConsole.TranslationLayer +{ + using System.Collections.Generic; + using System.Threading.Tasks; + + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + using Microsoft.VisualStudio.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; + + /// + /// Defines a test session object that can be used to make calls to the vstest.console + /// process. + /// + public class TestSession : ITestSession + { + private TestSessionInfo testSessionInfo; + private VsTestConsoleWrapper consoleWrapper; + + #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// + /// The test session info object. + /// The encapsulated console wrapper. + public TestSession( + TestSessionInfo testSessionInfo, + VsTestConsoleWrapper consoleWrapper) + { + this.testSessionInfo = testSessionInfo; + this.consoleWrapper = consoleWrapper; + } + #endregion + + #region ITestSession + /// + public void AbortTestRun() + { + this.consoleWrapper.AbortTestRun(); + } + + /// + public void CancelDiscovery() + { + this.consoleWrapper.CancelDiscovery(); + } + + /// + public void CancelTestRun() + { + this.consoleWrapper.CancelTestRun(); + } + + /// + public void DiscoverTests( + IEnumerable sources, + string discoverySettings, + ITestDiscoveryEventsHandler discoveryEventsHandler) + { + this.DiscoverTests( + sources, + discoverySettings, + options: null, + discoveryEventsHandler: new DiscoveryEventsHandleConverter(discoveryEventsHandler)); + } + + /// + public void DiscoverTests( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler) + { + // TODO (copoiena): Hook into the wrapper and pass session info here. + this.consoleWrapper.DiscoverTests( + sources, + discoverySettings, + options, + discoveryEventsHandler); + } + + /// + public void RunTests( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler) + { + this.RunTests( + sources, + runSettings, + options: null, + testRunEventsHandler); + } + + /// + public void RunTests( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler) + { + this.consoleWrapper.RunTests( + sources, + runSettings, + options, + this.testSessionInfo, + testRunEventsHandler); + } + + /// + public void RunTests( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler) + { + this.RunTests( + testCases, + runSettings, + options: null, + testRunEventsHandler); + } + + /// + public void RunTests( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler) + { + this.consoleWrapper.RunTests( + testCases, + runSettings, + options, + this.testSessionInfo, + testRunEventsHandler); + } + + /// + public void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + this.RunTestsWithCustomTestHost( + sources, + runSettings, + options: null, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + this.consoleWrapper.RunTestsWithCustomTestHost( + sources, + runSettings, + options, + this.testSessionInfo, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + this.RunTestsWithCustomTestHost( + testCases, + runSettings, + options: null, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + this.consoleWrapper.RunTestsWithCustomTestHost( + testCases, + runSettings, + options, + this.testSessionInfo, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public bool StopTestSession(ITestSessionEventsHandler eventsHandler) + { + return this.consoleWrapper.StopTestSession( + this.testSessionInfo, + eventsHandler); + } + #endregion + + #region ITestSessionAsync + /// + public async Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + ITestDiscoveryEventsHandler discoveryEventsHandler) + { + await this.DiscoverTestsAsync( + sources, + discoverySettings, + options: null, + discoveryEventsHandler: new DiscoveryEventsHandleConverter(discoveryEventsHandler)); + } + + /// + public async Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler) + { + // TODO (copoiena): Hook into the wrapper and pass session info here. + await this.consoleWrapper.DiscoverTestsAsync( + sources, + discoverySettings, + options, + discoveryEventsHandler); + } + + /// + public async Task RunTestsAsync( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler) + { + await this.RunTestsAsync( + sources, + runSettings, + options: null, + testRunEventsHandler); + } + + /// + public async Task RunTestsAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler) + { + await this.consoleWrapper.RunTestsAsync( + sources, + runSettings, + options, + this.testSessionInfo, + testRunEventsHandler); + } + + /// + public async Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler) + { + await this.RunTestsAsync( + testCases, + runSettings, + options: null, + testRunEventsHandler); + } + + /// + public async Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler) + { + await this.consoleWrapper.RunTestsAsync( + testCases, + runSettings, + options, + this.testSessionInfo, + testRunEventsHandler); + } + + /// + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + await this.RunTestsWithCustomTestHostAsync( + sources, + runSettings, + options: null, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + await this.consoleWrapper.RunTestsWithCustomTestHostAsync( + sources, + runSettings, + options, + this.testSessionInfo, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + await this.RunTestsWithCustomTestHostAsync( + testCases, + runSettings, + options: null, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + await this.consoleWrapper.RunTestsWithCustomTestHostAsync( + testCases, + runSettings, + options, + this.testSessionInfo, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public async Task StopTestSessionAsync(ITestSessionEventsHandler eventsHandler) + { + return await this.consoleWrapper.StopTestSessionAsync( + this.testSessionInfo, + eventsHandler); + } + #endregion + } +} diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index 2529e8c6bf..35c7630730 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -19,15 +19,21 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using TranslationLayerResources = Microsoft.VisualStudio.TestPlatform.VsTestConsole.TranslationLayer.Resources.Resources; /// - /// VstestConsoleRequestSender for sending requests to Vstest.console.exe + /// Vstest console request sender for sending requests to vstest.console.exe /// internal class VsTestConsoleRequestSender : ITranslationLayerRequestSender { + /// + /// The minimum protocol version that has test session support. + /// + private const int MinimumProtocolVersionWithTestSessionSupport = 5; + private readonly ICommunicationManager communicationManager; private readonly IDataSerializer dataSerializer; @@ -37,20 +43,37 @@ internal class VsTestConsoleRequestSender : ITranslationLayerRequestSender private bool handShakeSuccessful = false; - private int protocolVersion = 4; + private int protocolVersion = 5; /// - /// Use to cancel blocking tasks associated with vstest.console process + /// Used to cancel blocking tasks associated with the vstest.console process. /// private CancellationTokenSource processExitCancellationTokenSource; #region Constructor - public VsTestConsoleRequestSender() : this(new SocketCommunicationManager(), JsonDataSerializer.Instance, TestPlatformEventSource.Instance) + /// + /// Initializes a new instance of the class. + /// + public VsTestConsoleRequestSender() + : this( + new SocketCommunicationManager(), + JsonDataSerializer.Instance, + TestPlatformEventSource.Instance) { } - internal VsTestConsoleRequestSender(ICommunicationManager communicationManager, IDataSerializer dataSerializer, ITestPlatformEventSource testPlatformEventSource) + /// + /// Initializes a new instance of the class. + /// + /// + /// The communication manager. + /// The data serializer. + /// The test platform event source. + internal VsTestConsoleRequestSender( + ICommunicationManager communicationManager, + IDataSerializer dataSerializer, + ITestPlatformEventSource testPlatformEventSource) { this.communicationManager = communicationManager; this.dataSerializer = dataSerializer; @@ -61,11 +84,7 @@ internal VsTestConsoleRequestSender(ICommunicationManager communicationManager, #region ITranslationLayerRequestSender - /// - /// Initializes Communication with vstest.console.exe - /// Hosts a communication channel and asynchronously connects to vstest.console.exe - /// - /// Port Number of hosted server on this side + /// public int InitializeCommunication() { if (EqtTrace.IsInfoEnabled) @@ -91,7 +110,9 @@ public int InitializeCommunication() } catch (Exception ex) { - EqtTrace.Error("VsTestConsoleRequestSender.InitializeCommunication: Error initializing communication with VstestConsole: {0}", ex); + EqtTrace.Error( + "VsTestConsoleRequestSender.InitializeCommunication: Error initializing communication with VstestConsole: {0}", + ex); this.handShakeComplete.Set(); } @@ -103,11 +124,7 @@ public int InitializeCommunication() return port; } - /// - /// Waits for Vstest.console.exe Connection for a given timeout. - /// - /// Time to wait for the connection - /// True, if successful + /// public bool WaitForRequestHandlerConnection(int clientConnectionTimeout) { var waitSucess = this.handShakeComplete.WaitOne(clientConnectionTimeout); @@ -130,14 +147,17 @@ public async Task InitializeCommunicationAsync(int clientConnectionTimeout) { port = this.communicationManager.HostServer(new IPEndPoint(IPAddress.Loopback, 0)).Port; var timeoutSource = new CancellationTokenSource(clientConnectionTimeout); - await Task.Run(() => this.communicationManager.AcceptClientAsync(), timeoutSource.Token); + await Task.Run(() => + this.communicationManager.AcceptClientAsync(), timeoutSource.Token); this.handShakeSuccessful = await this.HandShakeWithVsTestConsoleAsync(); this.handShakeComplete.Set(); } catch (Exception ex) { - EqtTrace.Error("VsTestConsoleRequestSender.InitializeCommunicationAsync: Error initializing communication with VstestConsole: {0}", ex); + EqtTrace.Error( + "VsTestConsoleRequestSender.InitializeCommunicationAsync: Error initializing communication with VstestConsole: {0}", + ex); this.handShakeComplete.Set(); } @@ -156,33 +176,58 @@ public void InitializeExtensions(IEnumerable pathToAdditionalExtensions) { EqtTrace.Info($"VsTestConsoleRequestSender.InitializeExtensions: Initializing extensions with additional extensions path {string.Join(",", pathToAdditionalExtensions.ToList())}."); } - this.communicationManager.SendMessage(MessageType.ExtensionsInitialize, pathToAdditionalExtensions, this.protocolVersion); + + this.communicationManager.SendMessage( + MessageType.ExtensionsInitialize, + pathToAdditionalExtensions, + this.protocolVersion); } /// - public void DiscoverTests(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 eventHandler) + public void DiscoverTests( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 eventHandler) { if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("VsTestConsoleRequestSender.DiscoverTests: Starting test discovery."); } - this.SendMessageAndListenAndReportTestCases(sources, runSettings, options, eventHandler); + + this.SendMessageAndListenAndReportTestCases( + sources, + runSettings, + options, + eventHandler); } - /// - /// Asynchronous equivalent of . - /// - public async Task DiscoverTestsAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 eventHandler) + /// + public async Task DiscoverTestsAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 eventHandler) { if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("VsTestConsoleRequestSender.DiscoverTestsAsync: Starting test discovery."); } - await this.SendMessageAndListenAndReportTestCasesAsync(sources, runSettings, options, eventHandler); + + await this.SendMessageAndListenAndReportTestCasesAsync( + sources, + runSettings, + options, + eventHandler); } /// - public void StartTestRun(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler) + public void StartTestRun( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler) { if (EqtTrace.IsInfoEnabled) { @@ -191,41 +236,76 @@ public void StartTestRun(IEnumerable sources, string runSettings, TestPl this.SendMessageAndListenAndReportTestResults( MessageType.TestRunAllSourcesWithDefaultHost, - new TestRunRequestPayload() { Sources = sources.ToList(), RunSettings = runSettings, TestPlatformOptions = options }, + new TestRunRequestPayload() + { + Sources = sources.ToList(), + RunSettings = runSettings, + TestPlatformOptions = options, + TestSessionInfo = testSessionInfo + }, runEventsHandler, null); } /// - public async Task StartTestRunAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler) + public async Task StartTestRunAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler) { if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("VsTestConsoleRequestSender.StartTestRunAsync: Starting test run."); } + await this.SendMessageAndListenAndReportTestResultsAsync( MessageType.TestRunAllSourcesWithDefaultHost, - new TestRunRequestPayload() { Sources = sources.ToList(), RunSettings = runSettings, TestPlatformOptions = options }, + new TestRunRequestPayload() + { + Sources = sources.ToList(), + RunSettings = runSettings, + TestPlatformOptions = options, + TestSessionInfo = testSessionInfo + }, runEventsHandler, null); } /// - public void StartTestRun(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler) + public void StartTestRun( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler) { if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("VsTestConsoleRequestSender.StartTestRun: Starting test run."); } + this.SendMessageAndListenAndReportTestResults( MessageType.TestRunAllSourcesWithDefaultHost, - new TestRunRequestPayload() { TestCases = testCases.ToList(), RunSettings = runSettings, TestPlatformOptions = options }, + new TestRunRequestPayload() + { + TestCases = testCases.ToList(), + RunSettings = runSettings, + TestPlatformOptions = options, + TestSessionInfo = testSessionInfo + }, runEventsHandler, null); } /// - public async Task StartTestRunAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler) + public async Task StartTestRunAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler) { if (EqtTrace.IsInfoEnabled) { @@ -234,7 +314,13 @@ public async Task StartTestRunAsync(IEnumerable testCases, string runS await this.SendMessageAndListenAndReportTestResultsAsync( MessageType.TestRunAllSourcesWithDefaultHost, - new TestRunRequestPayload() { TestCases = testCases.ToList(), RunSettings = runSettings, TestPlatformOptions = options }, + new TestRunRequestPayload() + { + TestCases = testCases.ToList(), + RunSettings = runSettings, + TestPlatformOptions = options, + TestSessionInfo = testSessionInfo + }, runEventsHandler, null); } @@ -244,6 +330,7 @@ public void StartTestRunWithCustomHost( IEnumerable sources, string runSettings, TestPlatformOptions options, + TestSessionInfo testSessionInfo, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customHostLauncher) { @@ -259,7 +346,8 @@ public void StartTestRunWithCustomHost( Sources = sources.ToList(), RunSettings = runSettings, DebuggingEnabled = customHostLauncher.IsDebug, - TestPlatformOptions = options + TestPlatformOptions = options, + TestSessionInfo = testSessionInfo }, runEventsHandler, customHostLauncher); @@ -270,6 +358,7 @@ public async Task StartTestRunWithCustomHostAsync( IEnumerable sources, string runSettings, TestPlatformOptions options, + TestSessionInfo testSessionInfo, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customHostLauncher) { @@ -285,14 +374,21 @@ await this.SendMessageAndListenAndReportTestResultsAsync( Sources = sources.ToList(), RunSettings = runSettings, DebuggingEnabled = customHostLauncher.IsDebug, - TestPlatformOptions = options + TestPlatformOptions = options, + TestSessionInfo = testSessionInfo }, runEventsHandler, customHostLauncher); } /// - public void StartTestRunWithCustomHost(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customHostLauncher) + public void StartTestRunWithCustomHost( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler, + ITestHostLauncher customHostLauncher) { if (EqtTrace.IsInfoEnabled) { @@ -306,14 +402,21 @@ public void StartTestRunWithCustomHost(IEnumerable testCases, string r TestCases = testCases.ToList(), RunSettings = runSettings, DebuggingEnabled = customHostLauncher.IsDebug, - TestPlatformOptions = options + TestPlatformOptions = options, + TestSessionInfo = testSessionInfo }, runEventsHandler, customHostLauncher); } /// - public async Task StartTestRunWithCustomHostAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customHostLauncher) + public async Task StartTestRunWithCustomHostAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler runEventsHandler, + ITestHostLauncher customHostLauncher) { if (EqtTrace.IsInfoEnabled) { @@ -327,12 +430,377 @@ await this.SendMessageAndListenAndReportTestResultsAsync( TestCases = testCases.ToList(), RunSettings = runSettings, DebuggingEnabled = customHostLauncher.IsDebug, - TestPlatformOptions = options + TestPlatformOptions = options, + TestSessionInfo = testSessionInfo }, runEventsHandler, customHostLauncher); } + /// + public TestSessionInfo StartTestSession( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler, + ITestHostLauncher testHostLauncher) + { + // Make sure vstest.console knows how to handle start/stop test session messages. + // Bail out if it doesn't, otherwise we'll hang waiting for a reply from the console + // that will never come. + if (this.protocolVersion < MinimumProtocolVersionWithTestSessionSupport) + { + eventsHandler?.HandleStartTestSessionComplete(null); + return null; + } + + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("VsTestConsoleRequestSender.StartTestSession: Starting test session."); + } + + try + { + var payload = new StartTestSessionPayload + { + // TODO (copoiena): When sharing the test host between test discovery and test + // execution, should we use the test host launcher to launch it ? What side + // effects does this have ? + // + // This is useful for profiling and maybe for launching hosts other than the + // ones managed by us (i.e., the default host and the dotnet host), examples + // including UWP and other hosts that don't implement the ITestRuntimeProvider2 + // interface and/or are not aware of the possibility of attaching to an already + // running process. + Sources = sources, + RunSettings = runSettings, + HasCustomHostLauncher = testHostLauncher != null, + IsDebuggingEnabled = (testHostLauncher != null) + ? testHostLauncher.IsDebug + : false, + TestPlatformOptions = options + }; + + this.communicationManager.SendMessage( + MessageType.StartTestSession, + payload, + this.protocolVersion); + + while (true) + { + var message = this.TryReceiveMessage(); + + switch (message.MessageType) + { + case MessageType.StartTestSessionCallback: + var ackPayload = this.dataSerializer + .DeserializePayload(message); + eventsHandler?.HandleStartTestSessionComplete( + ackPayload.TestSessionInfo); + return ackPayload.TestSessionInfo; + + case MessageType.CustomTestHostLaunch: + this.HandleCustomHostLaunch(testHostLauncher, message); + break; + + case MessageType.EditorAttachDebugger: + this.AttachDebuggerToProcess(testHostLauncher, message); + break; + + case MessageType.TestMessage: + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventsHandler?.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); + break; + + default: + EqtTrace.Warning( + "VsTestConsoleRequestSender.StartTestSession: Unexpected message received: {0}", + message.MessageType); + break; + } + } + } + catch (Exception exception) + { + EqtTrace.Error( + "Aborting StartTestSession operation due to error: {0}", + exception); + eventsHandler?.HandleLogMessage( + TestMessageLevel.Error, + TranslationLayerResources.AbortedStartTestSession); + + eventsHandler?.HandleStartTestSessionComplete(null); + } + + this.testPlatformEventSource.TranslationLayerStartTestSessionStop(); + return null; + } + + /// + public async Task StartTestSessionAsync( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler, + ITestHostLauncher testHostLauncher) + { + // Make sure vstest.console knows how to handle start/stop test session messages. + // Bail out if it doesn't, otherwise we'll hang waiting for a reply from the console + // that will never come. + if (this.protocolVersion < MinimumProtocolVersionWithTestSessionSupport) + { + eventsHandler?.HandleStartTestSessionComplete(null); + return await Task.FromResult((TestSessionInfo)null); + } + + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("VsTestConsoleRequestSender.StartTestSession: Starting test session."); + } + + try + { + var payload = new StartTestSessionPayload + { + // TODO (copoiena): When sharing the test host between test discovery and test + // execution, should we use the test host launcher to launch it ? What side + // effects does this have ? + // + // This is useful for profiling and maybe for launching hosts other than the + // ones managed by us (i.e., the default host and the dotnet host), examples + // including UWP and other hosts that don't implement the ITestRuntimeProvider2 + // interface and/or are not aware of the possibility of attaching to an already + // running process. + Sources = sources, + RunSettings = runSettings, + HasCustomHostLauncher = testHostLauncher != null, + IsDebuggingEnabled = (testHostLauncher != null) ? testHostLauncher.IsDebug : false, + TestPlatformOptions = options + }; + + this.communicationManager.SendMessage( + MessageType.StartTestSession, + payload, + this.protocolVersion); + + while (true) + { + var message = await this.TryReceiveMessageAsync().ConfigureAwait(false); + + switch (message.MessageType) + { + case MessageType.StartTestSessionCallback: + var ackPayload = this.dataSerializer + .DeserializePayload(message); + eventsHandler?.HandleStartTestSessionComplete( + ackPayload.TestSessionInfo); + return ackPayload.TestSessionInfo; + + case MessageType.CustomTestHostLaunch: + this.HandleCustomHostLaunch(testHostLauncher, message); + break; + + case MessageType.EditorAttachDebugger: + this.AttachDebuggerToProcess(testHostLauncher, message); + break; + + case MessageType.TestMessage: + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventsHandler?.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); + break; + + default: + EqtTrace.Warning( + "VsTestConsoleRequestSender.StartTestSession: Unexpected message received: {0}", + message.MessageType); + break; + } + } + } + catch (Exception exception) + { + EqtTrace.Error("Aborting StartTestSession operation due to error: {0}", exception); + eventsHandler?.HandleLogMessage( + TestMessageLevel.Error, + TranslationLayerResources.AbortedStartTestSession); + + eventsHandler?.HandleStartTestSessionComplete(null); + } + + this.testPlatformEventSource.TranslationLayerStartTestSessionStop(); + return null; + } + + /// + public bool StopTestSession( + TestSessionInfo testSessionInfo, + ITestSessionEventsHandler eventsHandler) + { + // Make sure vstest.console knows how to handle start/stop test session messages. + // Bail out if it doesn't, otherwise we'll hang waiting for a reply from the console + // that will never come. + if (this.protocolVersion < MinimumProtocolVersionWithTestSessionSupport) + { + eventsHandler?.HandleStopTestSessionComplete(testSessionInfo, false); + return false; + } + + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("VsTestConsoleRequestSender.StopTestSession: Stop test session."); + } + + // Due to various considertaions it is possible to end up with a null test session + // after doing the start test session call. However, we should filter out requests + // to stop such a session as soon as possible, at the request sender level. + // + // We do this here instead of on the wrapper level in order to benefit of the + // testplatform events being fired still. + if (testSessionInfo == null) + { + this.testPlatformEventSource.TranslationLayerStopTestSessionStop(); + return true; + } + + try + { + this.communicationManager.SendMessage( + MessageType.StopTestSession, + testSessionInfo, + this.protocolVersion); + + while (true) + { + var message = this.TryReceiveMessage(); + + switch (message.MessageType) + { + case MessageType.StopTestSessionCallback: + var payload = this.dataSerializer.DeserializePayload(message); + eventsHandler?.HandleStopTestSessionComplete(payload.TestSessionInfo, payload.IsStopped); + return payload.IsStopped; + + case MessageType.TestMessage: + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventsHandler?.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); + break; + + default: + EqtTrace.Warning( + "VsTestConsoleRequestSender.StopTestSession: Unexpected message received: {0}", + message.MessageType); + break; + } + } + } + catch (Exception exception) + { + EqtTrace.Error( + "Aborting StopTestSession operation for id {0} due to error: {1}", + testSessionInfo?.Id, + exception); + eventsHandler?.HandleLogMessage( + TestMessageLevel.Error, + TranslationLayerResources.AbortedStopTestSession); + + eventsHandler?.HandleStopTestSessionComplete(testSessionInfo, false); + } + + this.testPlatformEventSource.TranslationLayerStopTestSessionStop(); + return false; + } + + /// + public async Task StopTestSessionAsync( + TestSessionInfo testSessionInfo, + ITestSessionEventsHandler eventsHandler) + { + // Make sure vstest.console knows how to handle start/stop test session messages. + // Bail out if it doesn't, otherwise we'll hang waiting for a reply from the console + // that will never come. + if (this.protocolVersion < MinimumProtocolVersionWithTestSessionSupport) + { + eventsHandler?.HandleStopTestSessionComplete(testSessionInfo, false); + return await Task.FromResult(false); + } + + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("VsTestConsoleRequestSender.StopTestSession: Stop test session."); + } + + // Due to various considertaions it is possible to end up with a null test session + // after doing the start test session call. However, we should filter out requests + // to stop such a session as soon as possible, at the request sender level. + // + // We do this here instead of on the wrapper level in order to benefit of the + // testplatform events being fired still. + if (testSessionInfo == null) + { + this.testPlatformEventSource.TranslationLayerStopTestSessionStop(); + return true; + } + + try + { + this.communicationManager.SendMessage( + MessageType.StopTestSession, + testSessionInfo, + this.protocolVersion); + + while (true) + { + var message = await this.TryReceiveMessageAsync().ConfigureAwait(false); + + switch (message.MessageType) + { + case MessageType.StopTestSessionCallback: + var payload = this.dataSerializer.DeserializePayload(message); + eventsHandler?.HandleStopTestSessionComplete(payload.TestSessionInfo, payload.IsStopped); + return payload.IsStopped; + + case MessageType.TestMessage: + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventsHandler?.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); + break; + + default: + EqtTrace.Warning( + "VsTestConsoleRequestSender.StopTestSession: Unexpected message received: {0}", + message.MessageType); + break; + } + } + } + catch (Exception exception) + { + EqtTrace.Error( + "Aborting StopTestSession operation for id {0} due to error: {1}", + testSessionInfo?.Id, + exception); + eventsHandler?.HandleLogMessage( + TestMessageLevel.Error, + TranslationLayerResources.AbortedStopTestSession); + + eventsHandler?.HandleStopTestSessionComplete(testSessionInfo, false); + } + + this.testPlatformEventSource.TranslationLayerStopTestSessionStop(); + return false; + } + /// public void CancelTestRun() { @@ -340,6 +808,7 @@ public void CancelTestRun() { EqtTrace.Info("VsTestConsoleRequestSender.CancelTestRun: Canceling test run."); } + this.communicationManager.SendMessage(MessageType.CancelTestRun); } @@ -350,6 +819,7 @@ public void AbortTestRun() { EqtTrace.Info("VsTestConsoleRequestSender.AbortTestRun: Aborting test run."); } + this.communicationManager.SendMessage(MessageType.AbortTestRun); } @@ -360,6 +830,7 @@ public void CancelDiscovery() { EqtTrace.Info("VsTestConsoleRequestSender.CancelDiscovery: Canceling test discovery."); } + this.communicationManager.SendMessage(MessageType.CancelDiscovery); } @@ -375,23 +846,27 @@ public void Close() this.Dispose(); } - /// - /// Sends message for terminating the session - /// + /// public void EndSession() { this.communicationManager.SendMessage(MessageType.SessionEnd); } /// - public Task ProcessTestRunAttachmentsAsync(IEnumerable attachments, bool collectMetrics, ITestRunAttachmentsProcessingEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) + public Task ProcessTestRunAttachmentsAsync( + IEnumerable attachments, + bool collectMetrics, + ITestRunAttachmentsProcessingEventsHandler testSessionEventsHandler, + CancellationToken cancellationToken) { - return this.SendMessageAndListenAndReportAttachmentsProcessingResultAsync(attachments, collectMetrics, testSessionEventsHandler, cancellationToken); + return this.SendMessageAndListenAndReportAttachmentsProcessingResultAsync( + attachments, + collectMetrics, + testSessionEventsHandler, + cancellationToken); } - /// - /// Closes the communication channel - /// + /// public void Dispose() { this.communicationManager?.StopServer(); @@ -403,29 +878,39 @@ private bool HandShakeWithVsTestConsole() { var success = false; var message = this.communicationManager.ReceiveMessage(); + if (message.MessageType == MessageType.SessionConnected) { - this.communicationManager.SendMessage(MessageType.VersionCheck, this.protocolVersion); + this.communicationManager.SendMessage( + MessageType.VersionCheck, + this.protocolVersion); + message = this.communicationManager.ReceiveMessage(); if (message.MessageType == MessageType.VersionCheck) { - this.protocolVersion = this.dataSerializer.DeserializePayload(message); + this.protocolVersion = this.dataSerializer + .DeserializePayload(message); success = true; } else if (message.MessageType == MessageType.ProtocolError) { // TODO : Payload for ProtocolError needs to finalized. - EqtTrace.Error("VsTestConsoleRequestSender.HandShakeWithVsTestConsole: Version Check failed. ProtolError was received from the runner"); + EqtTrace.Error( + "VsTestConsoleRequestSender.HandShakeWithVsTestConsole: Version Check failed. ProtolError was received from the runner"); } else { - EqtTrace.Error("VsTestConsoleRequestSender.HandShakeWithVsTestConsole: VersionCheck Message Expected but different message received: Received MessageType: {0}", message.MessageType); + EqtTrace.Error( + "VsTestConsoleRequestSender.HandShakeWithVsTestConsole: VersionCheck Message Expected but different message received: Received MessageType: {0}", + message.MessageType); } } else { - EqtTrace.Error("VsTestConsoleRequestSender.HandShakeWithVsTestConsole: SessionConnected Message Expected but different message received: Received MessageType: {0}", message.MessageType); + EqtTrace.Error( + "VsTestConsoleRequestSender.HandShakeWithVsTestConsole: SessionConnected Message Expected but different message received: Received MessageType: {0}", + message.MessageType); } return success; @@ -434,11 +919,17 @@ private bool HandShakeWithVsTestConsole() private async Task HandShakeWithVsTestConsoleAsync() { var success = false; - var message = await this.communicationManager.ReceiveMessageAsync(this.processExitCancellationTokenSource.Token); + var message = await this.communicationManager.ReceiveMessageAsync( + this.processExitCancellationTokenSource.Token); + if (message.MessageType == MessageType.SessionConnected) { - this.communicationManager.SendMessage(MessageType.VersionCheck, this.protocolVersion); - message = await this.communicationManager.ReceiveMessageAsync(this.processExitCancellationTokenSource.Token); + this.communicationManager.SendMessage( + MessageType.VersionCheck, + this.protocolVersion); + + message = await this.communicationManager.ReceiveMessageAsync( + this.processExitCancellationTokenSource.Token); if (message.MessageType == MessageType.VersionCheck) { @@ -448,33 +939,49 @@ private async Task HandShakeWithVsTestConsoleAsync() else if (message.MessageType == MessageType.ProtocolError) { // TODO : Payload for ProtocolError needs to finalized. - EqtTrace.Error("VsTestConsoleRequestSender.HandShakeWithVsTestConsoleAsync: Version Check failed. ProtolError was received from the runner"); + EqtTrace.Error( + "VsTestConsoleRequestSender.HandShakeWithVsTestConsoleAsync: Version Check failed. ProtolError was received from the runner"); } else { - EqtTrace.Error("VsTestConsoleRequestSender.HandShakeWithVsTestConsoleAsync: VersionCheck Message Expected but different message received: Received MessageType: {0}", message.MessageType); + EqtTrace.Error( + "VsTestConsoleRequestSender.HandShakeWithVsTestConsoleAsync: VersionCheck Message Expected but different message received: Received MessageType: {0}", + message.MessageType); } } else { - EqtTrace.Error("VsTestConsoleRequestSender.HandShakeWithVsTestConsoleAsync: SessionConnected Message Expected but different message received: Received MessageType: {0}", message.MessageType); + EqtTrace.Error( + "VsTestConsoleRequestSender.HandShakeWithVsTestConsoleAsync: SessionConnected Message Expected but different message received: Received MessageType: {0}", + message.MessageType); } return success; } - private void SendMessageAndListenAndReportTestCases(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 eventHandler) + private void SendMessageAndListenAndReportTestCases( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 eventHandler) { try { this.communicationManager.SendMessage( - MessageType.StartDiscovery, - new DiscoveryRequestPayload() { Sources = sources, RunSettings = runSettings, TestPlatformOptions = options }, - this.protocolVersion); + MessageType.StartDiscovery, + new DiscoveryRequestPayload() + { + Sources = sources, + RunSettings = runSettings, + TestPlatformOptions = options + }, + this.protocolVersion); var isDiscoveryComplete = false; - // Cycle through the messages that the vstest.console sends. - // Currently each of the operations are not separate tasks since they should not each take much time. + // Cycle through the messages that vstest.console sends. + // Currently each operation is not a separate task since it should not take that + // much time to complete. + // // This is just a notification. while (!isDiscoveryComplete) { @@ -482,7 +989,8 @@ private void SendMessageAndListenAndReportTestCases(IEnumerable sources, if (string.Equals(MessageType.TestCasesFound, message.MessageType)) { - var testCases = this.dataSerializer.DeserializePayload>(message); + var testCases = this.dataSerializer + .DeserializePayload>(message); eventHandler.HandleDiscoveredTests(testCases); } @@ -490,15 +998,19 @@ private void SendMessageAndListenAndReportTestCases(IEnumerable sources, { if (EqtTrace.IsInfoEnabled) { - EqtTrace.Info("VsTestConsoleRequestSender.SendMessageAndListenAndReportTestCases: Discovery complete."); + EqtTrace.Info( + "VsTestConsoleRequestSender.SendMessageAndListenAndReportTestCases: Discovery complete."); } var discoveryCompletePayload = - this.dataSerializer.DeserializePayload(message); + this.dataSerializer + .DeserializePayload(message); - var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(discoveryCompletePayload.TotalTests, discoveryCompletePayload.IsAborted); + var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( + discoveryCompletePayload.TotalTests, + discoveryCompletePayload.IsAborted); - // Adding Metrics From VsTestConsole + // Adding metrics from vstest.console. discoveryCompleteEventArgs.Metrics = discoveryCompletePayload.Metrics; eventHandler.HandleDiscoveryComplete( @@ -508,39 +1020,57 @@ private void SendMessageAndListenAndReportTestCases(IEnumerable sources, } else if (string.Equals(MessageType.TestMessage, message.MessageType)) { - var testMessagePayload = this.dataSerializer.DeserializePayload(message); - eventHandler.HandleLogMessage(testMessagePayload.MessageLevel, testMessagePayload.Message); + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventHandler.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); } } } catch (Exception exception) { EqtTrace.Error("Aborting Test Discovery Operation: {0}", exception); - eventHandler.HandleLogMessage(TestMessageLevel.Error, TranslationLayerResources.AbortedTestsDiscovery); + eventHandler.HandleLogMessage( + TestMessageLevel.Error, + TranslationLayerResources.AbortedTestsDiscovery); var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(-1, true); eventHandler.HandleDiscoveryComplete(discoveryCompleteEventArgs, null); - // Earlier we were closing the connection with vstest.console in case of exceptions - // Removing that code because vstest.console might be in a healthy state and letting the client - // know of the error, so that the TL can wait for the next instruction from the client itself. - // Also, connection termination might not kill the process which could result in files being locked by testhost. + // Earlier we were closing the connection with vstest.console in case of exceptions. + // Removing that code because vstest.console might be in a healthy state and letting + // the client know of the error, so that the TL can wait for the next instruction + // from the client itself. + // Also, connection termination might not kill the process which could result in + // files being locked by testhost. } this.testPlatformEventSource.TranslationLayerDiscoveryStop(); } - private async Task SendMessageAndListenAndReportTestCasesAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 eventHandler) + private async Task SendMessageAndListenAndReportTestCasesAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 eventHandler) { try { this.communicationManager.SendMessage( - MessageType.StartDiscovery, - new DiscoveryRequestPayload() { Sources = sources, RunSettings = runSettings, TestPlatformOptions = options }, - this.protocolVersion); + MessageType.StartDiscovery, + new DiscoveryRequestPayload() + { + Sources = sources, + RunSettings = runSettings, + TestPlatformOptions = options + }, + this.protocolVersion); var isDiscoveryComplete = false; - // Cycle through the messages that the vstest.console sends. - // Currently each of the operations are not separate tasks since they should not each take much time. + // Cycle through the messages that vstest.console sends. + // Currently each operation is not a separate task since it should not take that + // much time to complete. + // // This is just a notification. while (!isDiscoveryComplete) { @@ -548,7 +1078,8 @@ private async Task SendMessageAndListenAndReportTestCasesAsync(IEnumerable>(message); + var testCases = this.dataSerializer + .DeserializePayload>(message); eventHandler.HandleDiscoveredTests(testCases); } @@ -556,13 +1087,16 @@ private async Task SendMessageAndListenAndReportTestCasesAsync(IEnumerable(message); - var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(discoveryCompletePayload.TotalTests, discoveryCompletePayload.IsAborted); + var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( + discoveryCompletePayload.TotalTests, + discoveryCompletePayload.IsAborted); // Adding Metrics from VsTestConsole discoveryCompleteEventArgs.Metrics = discoveryCompletePayload.Metrics; @@ -574,8 +1108,11 @@ private async Task SendMessageAndListenAndReportTestCasesAsync(IEnumerable(message); - eventHandler.HandleLogMessage(testMessagePayload.MessageLevel, testMessagePayload.Message); + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventHandler.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); } } } @@ -583,36 +1120,48 @@ private async Task SendMessageAndListenAndReportTestCasesAsync(IEnumerable( + var testRunChangedArgs = this.dataSerializer + .DeserializePayload( message); eventHandler.HandleTestRunStatsChange(testRunChangedArgs); } @@ -620,11 +1169,12 @@ private void SendMessageAndListenAndReportTestResults(string messageType, object { if (EqtTrace.IsInfoEnabled) { - EqtTrace.Info("VsTestConsoleRequestSender.SendMessageAndListenAndReportTestResults: Execution complete."); + EqtTrace.Info( + "VsTestConsoleRequestSender.SendMessageAndListenAndReportTestResults: Execution complete."); } - var testRunCompletePayload = - this.dataSerializer.DeserializePayload(message); + var testRunCompletePayload = this.dataSerializer + .DeserializePayload(message); eventHandler.HandleTestRunComplete( testRunCompletePayload.TestRunCompleteArgs, @@ -635,63 +1185,79 @@ private void SendMessageAndListenAndReportTestResults(string messageType, object } else if (string.Equals(MessageType.TestMessage, message.MessageType)) { - var testMessagePayload = this.dataSerializer.DeserializePayload(message); - eventHandler.HandleLogMessage(testMessagePayload.MessageLevel, testMessagePayload.Message); + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventHandler.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); } else if (string.Equals(MessageType.CustomTestHostLaunch, message.MessageType)) { - HandleCustomHostLaunch(customHostLauncher, message); + this.HandleCustomHostLaunch(customHostLauncher, message); } else if (string.Equals(MessageType.EditorAttachDebugger, message.MessageType)) { - AttachDebuggerToProcess(customHostLauncher, message); + this.AttachDebuggerToProcess(customHostLauncher, message); } } } catch (Exception exception) { EqtTrace.Error("Aborting Test Run Operation: {0}", exception); - eventHandler.HandleLogMessage(TestMessageLevel.Error, TranslationLayerResources.AbortedTestsRun); - var completeArgs = new TestRunCompleteEventArgs(null, false, true, exception, null, TimeSpan.Zero); + eventHandler.HandleLogMessage( + TestMessageLevel.Error, + TranslationLayerResources.AbortedTestsRun); + var completeArgs = new TestRunCompleteEventArgs( + null, false, true, exception, null, TimeSpan.Zero); eventHandler.HandleTestRunComplete(completeArgs, null, null, null); - // Earlier we were closing the connection with vstest.console in case of exceptions - // Removing that code because vstest.console might be in a healthy state and letting the client - // know of the error, so that the TL can wait for the next instruction from the client itself. - // Also, connection termination might not kill the process which could result in files being locked by testhost. + // Earlier we were closing the connection with vstest.console in case of exceptions. + // Removing that code because vstest.console might be in a healthy state and letting + // the client know of the error, so that the TL can wait for the next instruction + // from the client itself. + // Also, connection termination might not kill the process which could result in + // files being locked by testhost. } this.testPlatformEventSource.TranslationLayerExecutionStop(); } - private async Task SendMessageAndListenAndReportTestResultsAsync(string messageType, object payload, ITestRunEventsHandler eventHandler, ITestHostLauncher customHostLauncher) + private async Task SendMessageAndListenAndReportTestResultsAsync( + string messageType, + object payload, + ITestRunEventsHandler eventHandler, + ITestHostLauncher customHostLauncher) { try { this.communicationManager.SendMessage(messageType, payload, this.protocolVersion); var isTestRunComplete = false; - // Cycle through the messages that the testhost sends. - // Currently each of the operations are not separate tasks since they should not each take much time. This is just a notification. + // Cycle through the messages that vstest.console sends. + // Currently each operation is not a separate task since it should not take that + // much time to complete. + // + // This is just a notification. while (!isTestRunComplete) { var message = await this.TryReceiveMessageAsync(); if (string.Equals(MessageType.TestRunStatsChange, message.MessageType)) { - var testRunChangedArgs = this.dataSerializer.DeserializePayload( - message); + var testRunChangedArgs = this.dataSerializer + .DeserializePayload(message); eventHandler.HandleTestRunStatsChange(testRunChangedArgs); } else if (string.Equals(MessageType.ExecutionComplete, message.MessageType)) { if (EqtTrace.IsInfoEnabled) { - EqtTrace.Info("VsTestConsoleRequestSender.SendMessageAndListenAndReportTestResultsAsync: Execution complete."); + EqtTrace.Info( + "VsTestConsoleRequestSender.SendMessageAndListenAndReportTestResultsAsync: Execution complete."); } - var testRunCompletePayload = - this.dataSerializer.DeserializePayload(message); + var testRunCompletePayload = this.dataSerializer + .DeserializePayload(message); eventHandler.HandleTestRunComplete( testRunCompletePayload.TestRunCompleteArgs, @@ -702,36 +1268,48 @@ private async Task SendMessageAndListenAndReportTestResultsAsync(string messageT } else if (string.Equals(MessageType.TestMessage, message.MessageType)) { - var testMessagePayload = this.dataSerializer.DeserializePayload(message); - eventHandler.HandleLogMessage(testMessagePayload.MessageLevel, testMessagePayload.Message); + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventHandler.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); } else if (string.Equals(MessageType.CustomTestHostLaunch, message.MessageType)) { - HandleCustomHostLaunch(customHostLauncher, message); + this.HandleCustomHostLaunch(customHostLauncher, message); } else if (string.Equals(MessageType.EditorAttachDebugger, message.MessageType)) { - AttachDebuggerToProcess(customHostLauncher, message); + this.AttachDebuggerToProcess(customHostLauncher, message); } } } catch (Exception exception) { EqtTrace.Error("Aborting Test Run Operation: {0}", exception); - eventHandler.HandleLogMessage(TestMessageLevel.Error, TranslationLayerResources.AbortedTestsRun); - var completeArgs = new TestRunCompleteEventArgs(null, false, true, exception, null, TimeSpan.Zero); + eventHandler.HandleLogMessage( + TestMessageLevel.Error, + TranslationLayerResources.AbortedTestsRun); + var completeArgs = new TestRunCompleteEventArgs( + null, false, true, exception, null, TimeSpan.Zero); eventHandler.HandleTestRunComplete(completeArgs, null, null, null); - // Earlier we were closing the connection with vstest.console in case of exceptions - // Removing that code because vstest.console might be in a healthy state and letting the client - // know of the error, so that the TL can wait for the next instruction from the client itself. - // Also, connection termination might not kill the process which could result in files being locked by testhost. + // Earlier we were closing the connection with vstest.console in case of exceptions. + // Removing that code because vstest.console might be in a healthy state and letting + // the client know of the error, so that the TL can wait for the next instruction + // from the client itself. + // Also, connection termination might not kill the process which could result in + // files being locked by testhost. } this.testPlatformEventSource.TranslationLayerExecutionStop(); } - private async Task SendMessageAndListenAndReportAttachmentsProcessingResultAsync(IEnumerable attachments, bool collectMetrics, ITestRunAttachmentsProcessingEventsHandler eventHandler, CancellationToken cancellationToken) + private async Task SendMessageAndListenAndReportAttachmentsProcessingResultAsync( + IEnumerable attachments, + bool collectMetrics, + ITestRunAttachmentsProcessingEventsHandler eventHandler, + CancellationToken cancellationToken) { try { @@ -741,43 +1319,62 @@ private async Task SendMessageAndListenAndReportAttachmentsProcessingResultAsync CollectMetrics = collectMetrics }; - this.communicationManager.SendMessage(MessageType.TestRunAttachmentsProcessingStart, payload); + this.communicationManager.SendMessage( + MessageType.TestRunAttachmentsProcessingStart, + payload); var isTestRunAttachmentsProcessingComplete = false; - using (cancellationToken.Register(() => this.communicationManager.SendMessage(MessageType.TestRunAttachmentsProcessingCancel))) + using (cancellationToken.Register(() => + this.communicationManager.SendMessage(MessageType.TestRunAttachmentsProcessingCancel))) { - // Cycle through the messages that the vstest.console sends. - // Currently each of the operations are not separate tasks since they should not each take much time. + // Cycle through the messages that vstest.console sends. + // Currently each operation is not a separate task since it should not take that + // much time to complete. + // // This is just a notification. while (!isTestRunAttachmentsProcessingComplete) { var message = await this.TryReceiveMessageAsync().ConfigureAwait(false); - if (string.Equals(MessageType.TestRunAttachmentsProcessingComplete, message.MessageType)) + if (string.Equals( + MessageType.TestRunAttachmentsProcessingComplete, + message.MessageType)) { if (EqtTrace.IsInfoEnabled) { - EqtTrace.Info("VsTestConsoleRequestSender.SendMessageAndListenAndReportAttachments: Process complete."); + EqtTrace.Info( + "VsTestConsoleRequestSender.SendMessageAndListenAndReportAttachments: Process complete."); } - var testRunAttachmentsProcessingCompletePayload = this.dataSerializer.DeserializePayload(message); + var testRunAttachmentsProcessingCompletePayload = this.dataSerializer + .DeserializePayload(message); - eventHandler.HandleTestRunAttachmentsProcessingComplete(testRunAttachmentsProcessingCompletePayload.AttachmentsProcessingCompleteEventArgs, testRunAttachmentsProcessingCompletePayload.Attachments); + eventHandler.HandleTestRunAttachmentsProcessingComplete( + testRunAttachmentsProcessingCompletePayload.AttachmentsProcessingCompleteEventArgs, + testRunAttachmentsProcessingCompletePayload.Attachments); isTestRunAttachmentsProcessingComplete = true; } - else if (string.Equals(MessageType.TestRunAttachmentsProcessingProgress, message.MessageType)) + else if (string.Equals( + MessageType.TestRunAttachmentsProcessingProgress, + message.MessageType)) { - var testRunAttachmentsProcessingProgressPayload = this.dataSerializer.DeserializePayload(message); - eventHandler.HandleTestRunAttachmentsProcessingProgress(testRunAttachmentsProcessingProgressPayload.AttachmentsProcessingProgressEventArgs); + var testRunAttachmentsProcessingProgressPayload = this.dataSerializer + .DeserializePayload(message); + eventHandler.HandleTestRunAttachmentsProcessingProgress( + testRunAttachmentsProcessingProgressPayload.AttachmentsProcessingProgressEventArgs); } else if (string.Equals(MessageType.TestMessage, message.MessageType)) { - var testMessagePayload = this.dataSerializer.DeserializePayload(message); - eventHandler.HandleLogMessage(testMessagePayload.MessageLevel, testMessagePayload.Message); + var testMessagePayload = this.dataSerializer + .DeserializePayload(message); + eventHandler.HandleLogMessage( + testMessagePayload.MessageLevel, + testMessagePayload.Message); } else { - EqtTrace.Warning($"VsTestConsoleRequestSender.SendMessageAndListenAndReportAttachments: Unexpected message received {message.MessageType}."); + EqtTrace.Warning( + $"VsTestConsoleRequestSender.SendMessageAndListenAndReportAttachments: Unexpected message received {message.MessageType}."); } } } @@ -785,13 +1382,19 @@ private async Task SendMessageAndListenAndReportAttachmentsProcessingResultAsync catch (Exception exception) { EqtTrace.Error("Aborting Test Session End Operation: {0}", exception); - eventHandler.HandleLogMessage(TestMessageLevel.Error, TranslationLayerResources.AbortedTestRunAttachmentsProcessing); - eventHandler.HandleTestRunAttachmentsProcessingComplete(new TestRunAttachmentsProcessingCompleteEventArgs(false, exception), null); - - // Earlier we were closing the connection with vstest.console in case of exceptions - // Removing that code because vstest.console might be in a healthy state and letting the client - // know of the error, so that the TL can wait for the next instruction from the client itself. - // Also, connection termination might not kill the process which could result in files being locked by testhost. + eventHandler.HandleLogMessage( + TestMessageLevel.Error, + TranslationLayerResources.AbortedTestRunAttachmentsProcessing); + eventHandler.HandleTestRunAttachmentsProcessingComplete( + new TestRunAttachmentsProcessingCompleteEventArgs(false, exception), + null); + + // Earlier we were closing the connection with vstest.console in case of exceptions. + // Removing that code because vstest.console might be in a healthy state and letting + // the client know of the error, so that the TL can wait for the next instruction + // from the client itself. + // Also, connection termination might not kill the process which could result in + // files being locked by testhost. } finally { @@ -802,13 +1405,15 @@ private async Task SendMessageAndListenAndReportAttachmentsProcessingResultAsync private Message TryReceiveMessage() { Message message = null; - var receiverMessageTask = this.communicationManager.ReceiveMessageAsync(this.processExitCancellationTokenSource.Token); + var receiverMessageTask = this.communicationManager.ReceiveMessageAsync( + this.processExitCancellationTokenSource.Token); receiverMessageTask.Wait(); message = receiverMessageTask.Result; if (message == null) { - throw new TransationLayerException(TranslationLayerResources.FailedToReceiveMessage); + throw new TransationLayerException( + TranslationLayerResources.FailedToReceiveMessage); } return message; @@ -816,11 +1421,13 @@ private Message TryReceiveMessage() private async Task TryReceiveMessageAsync() { - Message message = await this.communicationManager.ReceiveMessageAsync(this.processExitCancellationTokenSource.Token); + Message message = await this.communicationManager.ReceiveMessageAsync( + this.processExitCancellationTokenSource.Token); if (message == null) { - throw new TransationLayerException(TranslationLayerResources.FailedToReceiveMessage); + throw new TransationLayerException( + TranslationLayerResources.FailedToReceiveMessage); } return message; @@ -828,34 +1435,48 @@ private async Task TryReceiveMessageAsync() private void HandleCustomHostLaunch(ITestHostLauncher customHostLauncher, Message message) { - var ackPayload = new CustomHostLaunchAckPayload() { HostProcessId = -1, ErrorMessage = null }; + var ackPayload = new CustomHostLaunchAckPayload() + { + HostProcessId = -1, + ErrorMessage = null + }; try { - var testProcessStartInfo = this.dataSerializer.DeserializePayload(message); + var testProcessStartInfo = this.dataSerializer + .DeserializePayload(message); ackPayload.HostProcessId = customHostLauncher != null - ? customHostLauncher.LaunchTestHost(testProcessStartInfo) - : -1; + ? customHostLauncher.LaunchTestHost(testProcessStartInfo) + : -1; } catch (Exception ex) { EqtTrace.Error("Error while launching custom host: {0}", ex); - // Vstest.console will send the abort message properly while cleaning up all the flow, so do not abort here - // Let the ack go through and let vstest.console handle the error + // Vstest.console will send the abort message properly while cleaning up all the + // flow, so do not abort here. + // Let the ack go through and let vstest.console handle the error. ackPayload.ErrorMessage = ex.Message; } finally { - // Always unblock the Vstest.console thread which is indefinitely waiting on this ACK - this.communicationManager.SendMessage(MessageType.CustomTestHostLaunchCallback, ackPayload, this.protocolVersion); + // Always unblock the vstest.console thread which is indefinitely waiting on this + // ACK. + this.communicationManager.SendMessage( + MessageType.CustomTestHostLaunchCallback, + ackPayload, + this.protocolVersion); } } private void AttachDebuggerToProcess(ITestHostLauncher customHostLauncher, Message message) { - var ackPayload = new EditorAttachDebuggerAckPayload() { Attached = false, ErrorMessage = null }; + var ackPayload = new EditorAttachDebuggerAckPayload() + { + Attached = false, + ErrorMessage = null + }; try { @@ -867,7 +1488,9 @@ private void AttachDebuggerToProcess(ITestHostLauncher customHostLauncher, Messa } catch (Exception ex) { - EqtTrace.Error("VsTestConsoleRequestSender.AttachDebuggerToProcess: Error while attaching debugger to process: {0}", ex); + EqtTrace.Error( + "VsTestConsoleRequestSender.AttachDebuggerToProcess: Error while attaching debugger to process: {0}", + ex); // vstest.console will send the abort message properly while cleaning up all the // flow, so do not abort here. @@ -876,8 +1499,12 @@ private void AttachDebuggerToProcess(ITestHostLauncher customHostLauncher, Messa } finally { - // Always unblock the vstest.console thread which is indefintitely waiting on this ACK. - this.communicationManager.SendMessage(MessageType.EditorAttachDebuggerCallback, ackPayload, this.protocolVersion); + // Always unblock the vstest.console thread which is indefintitely waiting on this + // ACK. + this.communicationManager.SendMessage( + MessageType.EditorAttachDebuggerCallback, + ackPayload, + this.protocolVersion); } } } diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs index eb8780bdf6..78adc5bb0c 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs @@ -9,6 +9,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer using System.Linq; using System.Threading; using System.Threading.Tasks; + using Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing; @@ -18,6 +19,8 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces; + using Microsoft.VisualStudio.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; + using CommunicationUtilitiesResources = Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Resources.Resources; using CoreUtilitiesConstants = Microsoft.VisualStudio.TestPlatform.CoreUtilities.Constants; @@ -56,33 +59,55 @@ public class VsTestConsoleWrapper : IVsTestConsoleWrapper /// /// Initializes a new instance of the class. /// + /// /// /// Path to the test runner vstest.console.exe. /// - public VsTestConsoleWrapper(string vstestConsolePath) : - this(vstestConsolePath, ConsoleParameters.Default) + public VsTestConsoleWrapper( + string vstestConsolePath) + : this( + vstestConsolePath, + ConsoleParameters.Default) { } /// /// Initializes a new instance of the class. /// + /// /// Path to the test runner vstest.console.exe. - /// The parameters to be passed onto the runner process - public VsTestConsoleWrapper(string vstestConsolePath, ConsoleParameters consoleParameters) : - this(new VsTestConsoleRequestSender(), new VsTestConsoleProcessManager(vstestConsolePath), consoleParameters, TestPlatformEventSource.Instance, new ProcessHelper()) + /// The parameters to be passed onto the runner process. + public VsTestConsoleWrapper( + string vstestConsolePath, + ConsoleParameters consoleParameters) + : this( + new VsTestConsoleRequestSender(), + new VsTestConsoleProcessManager(vstestConsolePath), + consoleParameters, + TestPlatformEventSource.Instance, + new ProcessHelper()) { } /// /// Initializes a new instance of the class. - /// Defined for testing /// + /// + /// Defined for testing purposes. + /// /// Path to the test runner vstest.console.exe. - /// Path to dotnet exe, needed for CI builds - /// The parameters to be passed onto the runner process - internal VsTestConsoleWrapper(string vstestConsolePath, string dotnetExePath, ConsoleParameters consoleParameters) : - this(new VsTestConsoleRequestSender(), new VsTestConsoleProcessManager(vstestConsolePath, dotnetExePath), consoleParameters, TestPlatformEventSource.Instance, new ProcessHelper()) + /// Path to dotnet exe, needed for CI builds. + /// The parameters to be passed onto the runner process. + internal VsTestConsoleWrapper( + string vstestConsolePath, + string dotnetExePath, + ConsoleParameters consoleParameters) + : this( + new VsTestConsoleRequestSender(), + new VsTestConsoleProcessManager(vstestConsolePath, dotnetExePath), + consoleParameters, + TestPlatformEventSource.Instance, + new ProcessHelper()) { } @@ -90,12 +115,18 @@ internal VsTestConsoleWrapper(string vstestConsolePath, string dotnetExePath, Co /// /// Initializes a new instance of the class. /// + /// /// Sender for test messages. /// Process manager. - /// The parameters to be passed onto the runner process - /// Performance event source - /// Helper for process related utilities - internal VsTestConsoleWrapper(ITranslationLayerRequestSender requestSender, IProcessManager processManager, ConsoleParameters consoleParameters, ITestPlatformEventSource testPlatformEventSource, IProcessHelper processHelper) + /// The parameters to be passed onto the runner process. + /// Performance event source. + /// Helper for process related utilities. + internal VsTestConsoleWrapper( + ITranslationLayerRequestSender requestSender, + IProcessManager processManager, + ConsoleParameters consoleParameters, + ITestPlatformEventSource testPlatformEventSource, + IProcessHelper processHelper) { this.requestSender = requestSender; this.vstestConsoleProcessManager = processManager; @@ -152,22 +183,49 @@ public void InitializeExtensions(IEnumerable pathToAdditionalExtensions) } /// - public void DiscoverTests(IEnumerable sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) + public void DiscoverTests( + IEnumerable sources, + string discoverySettings, + ITestDiscoveryEventsHandler discoveryEventsHandler) { - this.testPlatformEventSource.TranslationLayerDiscoveryStart(); - this.EnsureInitialized(); + this.DiscoverTests( + sources, + discoverySettings, + options: null, + discoveryEventsHandler: new DiscoveryEventsHandleConverter(discoveryEventsHandler)); + } - // Converts ITestDiscoveryEventsHandler to ITestDiscoveryEventsHandler2 - var discoveryCompleteEventsHandler2 = new DiscoveryEventsHandleConverter(discoveryEventsHandler); - this.requestSender.DiscoverTests(sources, discoverySettings, options: null, discoveryEventsHandler: discoveryCompleteEventsHandler2); + /// + public void DiscoverTests( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler) + { + this.DiscoverTests( + sources, + discoverySettings, + options, + testSessionInfo: null, + discoveryEventsHandler); } /// - public void DiscoverTests(IEnumerable sources, string discoverySettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler) + public void DiscoverTests( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestDiscoveryEventsHandler2 discoveryEventsHandler) { this.testPlatformEventSource.TranslationLayerDiscoveryStart(); this.EnsureInitialized(); - this.requestSender.DiscoverTests(sources, discoverySettings, options, discoveryEventsHandler); + // TODO (copoiena): Add session info as a parameter. + this.requestSender.DiscoverTests( + sources, + discoverySettings, + options, + discoveryEventsHandler); } /// @@ -177,75 +235,285 @@ public void CancelDiscovery() } /// - public void RunTests(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler) + public void RunTests( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler) + { + this.RunTests( + sources, + runSettings, + options: null, + testRunEventsHandler: testRunEventsHandler); + } + + /// + public void RunTests( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler) { - this.RunTests(sources, runSettings, options: null, testRunEventsHandler: testRunEventsHandler); + this.RunTests( + sources, + runSettings, + options, + testSessionInfo: null, + testRunEventsHandler: testRunEventsHandler); } /// - public void RunTests(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler) + public void RunTests( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler) { var sourceList = sources.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, sourceList.Count, 0, runSettings ?? string.Empty); + this.testPlatformEventSource.TranslationLayerExecutionStart( + 0, + sourceList.Count, + 0, + runSettings ?? string.Empty); this.EnsureInitialized(); - this.requestSender.StartTestRun(sourceList, runSettings, options, testRunEventsHandler); + this.requestSender.StartTestRun( + sourceList, + runSettings, + options, + testSessionInfo, + testRunEventsHandler); } /// - public void RunTests(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler) + public void RunTests( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler) { - var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, 0, testCaseList.Count, runSettings ?? string.Empty); + this.RunTests( + testCases, + runSettings, + options: null, + testRunEventsHandler); + } - this.EnsureInitialized(); - this.requestSender.StartTestRun(testCaseList, runSettings, options: null, runEventsHandler: testRunEventsHandler); + /// + public void RunTests( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler) + { + this.RunTests( + testCases, + runSettings, + options, + testSessionInfo: null, + testRunEventsHandler); } /// - public void RunTests(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler) + public void RunTests( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler) { var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, 0, testCaseList.Count, runSettings ?? string.Empty); + this.testPlatformEventSource.TranslationLayerExecutionStart( + 0, + 0, + testCaseList.Count, + runSettings ?? string.Empty); this.EnsureInitialized(); - this.requestSender.StartTestRun(testCaseList, runSettings, options, testRunEventsHandler); + this.requestSender.StartTestRun( + testCaseList, + runSettings, + options, + testSessionInfo, + testRunEventsHandler); } /// - public void RunTestsWithCustomTestHost(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + public void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) { - this.RunTestsWithCustomTestHost(sources, runSettings, options: null, testRunEventsHandler: testRunEventsHandler, customTestHostLauncher: customTestHostLauncher); + this.RunTestsWithCustomTestHost( + sources, + runSettings, + options: null, + testRunEventsHandler: testRunEventsHandler, + customTestHostLauncher: customTestHostLauncher); } /// - public void RunTestsWithCustomTestHost(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + public void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + this.RunTestsWithCustomTestHost( + sources, + runSettings, + options, + testSessionInfo: null, + testRunEventsHandler: testRunEventsHandler, + customTestHostLauncher: customTestHostLauncher); + } + + /// + public void RunTestsWithCustomTestHost( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) { var sourceList = sources.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, sourceList.Count, 0, runSettings ?? string.Empty); + this.testPlatformEventSource.TranslationLayerExecutionStart( + 1, + sourceList.Count, + 0, + runSettings ?? string.Empty); this.EnsureInitialized(); - this.requestSender.StartTestRunWithCustomHost(sourceList, runSettings, options, testRunEventsHandler, customTestHostLauncher); + this.requestSender.StartTestRunWithCustomHost( + sourceList, + runSettings, + options, + testSessionInfo, + testRunEventsHandler, + customTestHostLauncher); } /// - public void RunTestsWithCustomTestHost(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + public void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + this.RunTestsWithCustomTestHost( + testCases, + runSettings, + options: null, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + this.RunTestsWithCustomTestHost( + testCases, + runSettings, + options, + testSessionInfo: null, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public void RunTestsWithCustomTestHost( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) { var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, 0, testCaseList.Count, runSettings ?? string.Empty); + this.testPlatformEventSource.TranslationLayerExecutionStart( + 1, + 0, + testCaseList.Count, + runSettings ?? string.Empty); this.EnsureInitialized(); - this.requestSender.StartTestRunWithCustomHost(testCaseList, runSettings, options: null, runEventsHandler: testRunEventsHandler, customTestHostLauncher: customTestHostLauncher); + this.requestSender.StartTestRunWithCustomHost( + testCaseList, + runSettings, + options, + testSessionInfo, + testRunEventsHandler, + customTestHostLauncher); } /// - public void RunTestsWithCustomTestHost(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + public ITestSession StartTestSession( + IList sources, + string runSettings, + ITestSessionEventsHandler eventsHandler) { - var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, 0, testCaseList.Count, runSettings ?? string.Empty); + return this.StartTestSession( + sources, + runSettings, + options: null, + eventsHandler); + } + + /// + public ITestSession StartTestSession( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler) + { + return this.StartTestSession( + sources, + runSettings, + options, + eventsHandler, + testHostLauncher: null); + } + + /// + public ITestSession StartTestSession( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler, + ITestHostLauncher testHostLauncher) + { + this.testPlatformEventSource.TranslationLayerStartTestSessionStart(); + + this.EnsureInitialized(); + return new TestSession( + this.requestSender.StartTestSession( + sources, + runSettings, + options, + eventsHandler, + testHostLauncher), + this); + } + + /// + public bool StopTestSession( + TestSessionInfo testSessionInfo, + ITestSessionEventsHandler eventsHandler) + { + this.testPlatformEventSource.TranslationLayerStopTestSessionStart(); this.EnsureInitialized(); - this.requestSender.StartTestRunWithCustomHost(testCaseList, runSettings, options, testRunEventsHandler, customTestHostLauncher); + return this.requestSender.StopTestSession( + testSessionInfo, + eventsHandler); } /// @@ -315,106 +583,352 @@ public async Task InitializeExtensionsAsync(IEnumerable pathToAdditional } /// - public async Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) + public async Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + ITestDiscoveryEventsHandler discoveryEventsHandler) { - this.testPlatformEventSource.TranslationLayerDiscoveryStart(); - await this.EnsureInitializedAsync(); - - // Converts ITestDiscoveryEventsHandler to ITestDiscoveryEventsHandler2 - var discoveryCompleteEventsHandler2 = new DiscoveryEventsHandleConverter(discoveryEventsHandler); - await this.requestSender.DiscoverTestsAsync(sources, discoverySettings, options: null, discoveryEventsHandler: discoveryCompleteEventsHandler2); + await this.DiscoverTestsAsync( + sources, + discoverySettings, + options: null, + discoveryEventsHandler: new DiscoveryEventsHandleConverter(discoveryEventsHandler)); } /// - public async Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler) + public async Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + ITestDiscoveryEventsHandler2 discoveryEventsHandler) + { + await this.DiscoverTestsAsync( + sources, + discoverySettings, + options, + testSessionInfo: null, + discoveryEventsHandler); + } + + /// + public async Task DiscoverTestsAsync( + IEnumerable sources, + string discoverySettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestDiscoveryEventsHandler2 discoveryEventsHandler) { this.testPlatformEventSource.TranslationLayerDiscoveryStart(); await this.EnsureInitializedAsync(); - await this.requestSender.DiscoverTestsAsync(sources, discoverySettings, options, discoveryEventsHandler); + await this.requestSender.DiscoverTestsAsync( + sources, + discoverySettings, + options, + // TODO(copoiena): Add session info as a parameter. + discoveryEventsHandler); } /// - public async Task RunTestsAsync(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler) + public async Task RunTestsAsync( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler) { - await RunTestsAsync(sources, runSettings, null, testRunEventsHandler); + await this.RunTestsAsync( + sources, + runSettings, + options: null, + testRunEventsHandler); } /// - public async Task RunTestsAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler) + public async Task RunTestsAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler) + { + await this.RunTestsAsync( + sources, + runSettings, + options, + testSessionInfo: null, + testRunEventsHandler); + } + + /// + public async Task RunTestsAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler) { var sourceList = sources.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, sourceList.Count, 0, runSettings ?? string.Empty); + this.testPlatformEventSource.TranslationLayerExecutionStart( + 0, + sourceList.Count, + 0, + runSettings ?? string.Empty); await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunAsync(sourceList, runSettings, options, testRunEventsHandler); + await this.requestSender.StartTestRunAsync( + sourceList, + runSettings, + options, + testSessionInfo, + testRunEventsHandler); } /// - public async Task RunTestsAsync(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler) + public async Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler) { - var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, 0, testCaseList.Count, runSettings ?? string.Empty); + await this.RunTestsAsync( + testCases, + runSettings, + options: null, + testRunEventsHandler); + } - await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunAsync(testCaseList, runSettings, options: null, runEventsHandler: testRunEventsHandler); + /// + public async Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler) + { + await this.RunTestsAsync( + testCases, + runSettings, + options, + testSessionInfo: null, + testRunEventsHandler); } /// - public async Task RunTestsAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler) + public async Task RunTestsAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler) { var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, 0, testCaseList.Count, runSettings ?? string.Empty); + this.testPlatformEventSource.TranslationLayerExecutionStart( + 0, + 0, + testCaseList.Count, + runSettings ?? string.Empty); await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunAsync(testCaseList, runSettings, options, testRunEventsHandler); + await this.requestSender.StartTestRunAsync( + testCaseList, + runSettings, + options, + testSessionInfo, + testRunEventsHandler); } /// - public async Task RunTestsWithCustomTestHostAsync(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) { - await RunTestsWithCustomTestHostAsync(sources, runSettings, null, testRunEventsHandler, customTestHostLauncher); + await this.RunTestsWithCustomTestHostAsync( + sources, + runSettings, + options: null, + testRunEventsHandler, + customTestHostLauncher); + } + + /// + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + await this.RunTestsWithCustomTestHostAsync( + sources, + runSettings, + options, + testSessionInfo: null, + testRunEventsHandler, + customTestHostLauncher); } /// - public async Task RunTestsWithCustomTestHostAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable sources, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) { var sourceList = sources.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, sourceList.Count, 0, runSettings ?? string.Empty); + this.testPlatformEventSource.TranslationLayerExecutionStart( + 1, + sourceList.Count, + 0, + runSettings ?? string.Empty); await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunWithCustomHostAsync(sourceList, runSettings, options, testRunEventsHandler, customTestHostLauncher); + await this.requestSender.StartTestRunWithCustomHostAsync( + sourceList, + runSettings, + options, + testSessionInfo, + testRunEventsHandler, + customTestHostLauncher); } /// - public async Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) { - var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, 0, testCaseList.Count, runSettings ?? string.Empty); + await this.RunTestsWithCustomTestHostAsync( + testCases, + runSettings, + options: null, + testRunEventsHandler, + customTestHostLauncher); + } - await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, runSettings, options: null, runEventsHandler: testRunEventsHandler, customTestHostLauncher: customTestHostLauncher); + /// + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) + { + await this.RunTestsWithCustomTestHostAsync( + testCases, + runSettings, + options, + testSessionInfo: null, + testRunEventsHandler, + customTestHostLauncher); } /// - public async Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + public async Task RunTestsWithCustomTestHostAsync( + IEnumerable testCases, + string runSettings, + TestPlatformOptions options, + TestSessionInfo testSessionInfo, + ITestRunEventsHandler testRunEventsHandler, + ITestHostLauncher customTestHostLauncher) { var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, 0, testCaseList.Count, runSettings ?? string.Empty); + this.testPlatformEventSource.TranslationLayerExecutionStart( + 1, + 0, + testCaseList.Count, + runSettings ?? string.Empty); await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, runSettings, options, testRunEventsHandler, customTestHostLauncher); + await this.requestSender.StartTestRunWithCustomHostAsync( + testCaseList, + runSettings, + options, + testSessionInfo, + testRunEventsHandler, + customTestHostLauncher); } /// - public async Task ProcessTestRunAttachmentsAsync(IEnumerable attachments, string processingSettings, bool isLastBatch, bool collectMetrics, ITestRunAttachmentsProcessingEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) + public async Task StartTestSessionAsync( + IList sources, + string runSettings, + ITestSessionEventsHandler eventsHandler) { - this.testPlatformEventSource.TranslationLayerTestRunAttachmentsProcessingStart(); + return await this.StartTestSessionAsync( + sources, + runSettings, + options: null, + eventsHandler).ConfigureAwait(false); + } + + /// + public async Task StartTestSessionAsync( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler) + { + return await this.StartTestSessionAsync( + sources, + runSettings, + options: null, + eventsHandler, + testHostLauncher: null).ConfigureAwait(false); + } + + /// + public async Task StartTestSessionAsync( + IList sources, + string runSettings, + TestPlatformOptions options, + ITestSessionEventsHandler eventsHandler, + ITestHostLauncher testHostLauncher) + { + this.testPlatformEventSource.TranslationLayerStartTestSessionStart(); await this.EnsureInitializedAsync().ConfigureAwait(false); - await requestSender.ProcessTestRunAttachmentsAsync(attachments, collectMetrics, testSessionEventsHandler, cancellationToken).ConfigureAwait(false); + return new TestSession( + await this.requestSender.StartTestSessionAsync( + sources, + runSettings, + options, + eventsHandler, + testHostLauncher).ConfigureAwait(false), + this); } + /// + public async Task StopTestSessionAsync( + TestSessionInfo testSessionInfo, + ITestSessionEventsHandler eventsHandler) + { + this.testPlatformEventSource.TranslationLayerStopTestSessionStart(); + + await this.EnsureInitializedAsync().ConfigureAwait(false); + return await this.requestSender.StopTestSessionAsync( + testSessionInfo, + eventsHandler).ConfigureAwait(false); + } + + /// + public async Task ProcessTestRunAttachmentsAsync( + IEnumerable attachments, + string processingSettings, + bool isLastBatch, + bool collectMetrics, + ITestRunAttachmentsProcessingEventsHandler testSessionEventsHandler, + CancellationToken cancellationToken) + { + this.testPlatformEventSource.TranslationLayerTestRunAttachmentsProcessingStart(); + + await this.EnsureInitializedAsync().ConfigureAwait(false); + await requestSender.ProcessTestRunAttachmentsAsync( + attachments, + collectMetrics, + testSessionEventsHandler, + cancellationToken).ConfigureAwait(false); + } #endregion diff --git a/src/vstest.console/CommandLine/InferHelper.cs b/src/vstest.console/CommandLine/InferHelper.cs index 3b3fc46edf..1c74b3e387 100644 --- a/src/vstest.console/CommandLine/InferHelper.cs +++ b/src/vstest.console/CommandLine/InferHelper.cs @@ -22,7 +22,7 @@ internal InferHelper(IAssemblyMetadataProvider assemblyMetadataProvider) /// /// Determines Architecture from sources. /// - public Architecture AutoDetectArchitecture(List sources, IDictionary sourcePlatforms, Architecture defaultArchitecture) + public Architecture AutoDetectArchitecture(IList sources, IDictionary sourcePlatforms, Architecture defaultArchitecture) { var architecture = defaultArchitecture; try @@ -86,7 +86,7 @@ public Architecture AutoDetectArchitecture(List sources, IDictionary /// Determines Framework from sources. /// - public Framework AutoDetectFramework(List sources, IDictionary sourceFrameworkVersions) + public Framework AutoDetectFramework(IList sources, IDictionary sourceFrameworkVersions) { Framework framework = Framework.DefaultFramework; try diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index 5832a59534..5ce2fdacb5 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -3,6 +3,16 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.TestPlatformHelpers { + using System; + using System.Xml; + using System.IO; + using System.Linq; + using System.Xml.XPath; + using System.Threading; + using System.Reflection; + using System.Threading.Tasks; + using System.Collections.Generic; + using Microsoft.VisualStudio.TestPlatform.Client; using Microsoft.VisualStudio.TestPlatform.Client.RequestHelper; using Microsoft.VisualStudio.TestPlatform.CommandLine.Internal; @@ -25,55 +35,53 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.TestPlatformHelpers using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces; using Microsoft.VisualStudio.TestPlatform.Utilities; - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Reflection; - using System.Threading; - using System.Threading.Tasks; - using System.Xml; - using System.Xml.XPath; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads; /// - /// Defines the TestRequestManger which can fire off discovery and test run requests + /// Defines the test request manger which can fire off discovery and test run requests. /// internal class TestRequestManager : ITestRequestManager { - private readonly ITestPlatform testPlatform; - private CommandLineOptions commandLineOptions; - private readonly ITestPlatformEventSource testPlatformEventSource; - private TestRunResultAggregator testRunResultAggregator; private static ITestRequestManager testRequestManagerInstance; - private InferHelper inferHelper; + private const int runRequestTimeout = 5000; - private bool telemetryOptedIn; - private readonly object syncObject = new object(); + + private readonly ITestPlatform testPlatform; + private readonly ITestPlatformEventSource testPlatformEventSource; private readonly Task metricsPublisher; + private readonly object syncObject = new object(); + private bool isDisposed; + private bool telemetryOptedIn; + private CommandLineOptions commandLineOptions; + private TestRunResultAggregator testRunResultAggregator; + private InferHelper inferHelper; private IProcessHelper processHelper; private ITestRunAttachmentsProcessingManager attachmentsProcessingManager; /// - /// Maintains the current active execution request - /// Assumption : There can only be one active execution request. + /// Maintains the current active execution request. + /// Assumption: There can only be one active execution request. /// private ITestRunRequest currentTestRunRequest; /// - /// Maintains the current active discovery request - /// Assumption : There can only be one active discovery request. + /// Maintains the current active discovery request. + /// Assumption: There can only be one active discovery request. /// private IDiscoveryRequest currentDiscoveryRequest; /// - /// Maintains the current active test run attachments processing cancellation token source - /// Assumption : There can only be one active attachments processing request. + /// Maintains the current active test run attachments processing cancellation token source. + /// Assumption: There can only be one active attachments processing request. /// private CancellationTokenSource currentAttachmentsProcessingCancellationTokenSource; #region Constructor + /// + /// Initializes a new instance of the class. + /// public TestRequestManager() : this( CommandLineOptions.Instance, @@ -81,13 +89,25 @@ public TestRequestManager() TestRunResultAggregator.Instance, TestPlatformEventSource.Instance, new InferHelper(AssemblyMetadataProvider.Instance), - MetricsPublisherFactory.GetMetricsPublisher(IsTelemetryOptedIn(), CommandLineOptions.Instance.IsDesignMode), + MetricsPublisherFactory.GetMetricsPublisher( + IsTelemetryOptedIn(), + CommandLineOptions.Instance.IsDesignMode), new ProcessHelper(), - new TestRunAttachmentsProcessingManager(TestPlatformEventSource.Instance, new CodeCoverageDataAttachmentsHandler())) + new TestRunAttachmentsProcessingManager( + TestPlatformEventSource.Instance, + new CodeCoverageDataAttachmentsHandler())) { } - internal TestRequestManager(CommandLineOptions commandLineOptions, ITestPlatform testPlatform, TestRunResultAggregator testRunResultAggregator, ITestPlatformEventSource testPlatformEventSource, InferHelper inferHelper, Task metricsPublisher, IProcessHelper processHelper, ITestRunAttachmentsProcessingManager attachmentsProcessingManager) + internal TestRequestManager( + CommandLineOptions commandLineOptions, + ITestPlatform testPlatform, + TestRunResultAggregator testRunResultAggregator, + ITestPlatformEventSource testPlatformEventSource, + InferHelper inferHelper, + Task metricsPublisher, + IProcessHelper processHelper, + ITestRunAttachmentsProcessingManager attachmentsProcessingManager) { this.testPlatform = testPlatform; this.commandLineOptions = commandLineOptions; @@ -101,6 +121,9 @@ internal TestRequestManager(CommandLineOptions commandLineOptions, ITestPlatform #endregion + /// + /// Gets the test request manager instance. + /// public static ITestRequestManager Instance { get @@ -117,33 +140,30 @@ public static ITestRequestManager Instance #region ITestRequestManager /// - public void InitializeExtensions(IEnumerable pathToAdditionalExtensions, bool skipExtensionFilters) + public void InitializeExtensions( + IEnumerable pathToAdditionalExtensions, + bool skipExtensionFilters) { - // It is possible for an Editor/IDE to keep running the runner in design mode for long duration. - // We clear the extensions cache to ensure the extensions don't get reused across discovery/run - // requests. + // It is possible for an Editor/IDE to keep running the runner in design mode for long + // duration. We clear the extensions cache to ensure the extensions don't get reused + // across discovery/run requests. EqtTrace.Info("TestRequestManager.InitializeExtensions: Initialize extensions started."); this.testPlatform.ClearExtensions(); this.testPlatform.UpdateExtensions(pathToAdditionalExtensions, skipExtensionFilters); EqtTrace.Info("TestRequestManager.InitializeExtensions: Initialize extensions completed."); } - /// - /// Resets the command options - /// + /// public void ResetOptions() { this.commandLineOptions.Reset(); } - /// - /// Discover Tests given a list of sources, run settings. - /// - /// Discovery payload - /// EventHandler for discovered tests - /// Protocol related information - /// True, if successful - public void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscoveryEventsRegistrar discoveryEventsRegistrar, ProtocolConfig protocolConfig) + /// + public void DiscoverTests( + DiscoveryRequestPayload discoveryPayload, + ITestDiscoveryEventsRegistrar discoveryEventsRegistrar, + ProtocolConfig protocolConfig) { EqtTrace.Info("TestRequestManager.DiscoverTests: Discovery tests started."); @@ -155,7 +175,11 @@ public void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscove } var requestData = this.GetRequestData(protocolConfig); - if (this.UpdateRunSettingsIfRequired(runsettings, discoveryPayload.Sources?.ToList(), discoveryEventsRegistrar, out string updatedRunsettings)) + if (this.UpdateRunSettingsIfRequired( + runsettings, + discoveryPayload.Sources?.ToList(), + discoveryEventsRegistrar, + out string updatedRunsettings)) { runsettings = updatedRunsettings; } @@ -166,34 +190,42 @@ public void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscove if (requestData.IsTelemetryOptedIn) { - // Collect Metrics + // Collect metrics. this.CollectMetrics(requestData, runConfiguration); - // Collect Commands + // Collect commands. this.LogCommandsTelemetryPoints(requestData); } - // create discovery request - var criteria = new DiscoveryCriteria(discoveryPayload.Sources, batchSize, this.commandLineOptions.TestStatsEventTimeout, runsettings) + // Create discovery request. + var criteria = new DiscoveryCriteria( + discoveryPayload.Sources, + batchSize, + this.commandLineOptions.TestStatsEventTimeout, + runsettings) { - TestCaseFilter = this.commandLineOptions.TestCaseFilterValue ?? testCaseFilterFromRunsettings + TestCaseFilter = this.commandLineOptions.TestCaseFilterValue + ?? testCaseFilterFromRunsettings }; - // Make sure to run the run request inside a lock as the below section is not thread-safe - // There can be only one discovery or execution request at a given point in time + // Make sure to run the run request inside a lock as the below section is not thread-safe. + // There can be only one discovery or execution request at a given point in time. lock (this.syncObject) { try { EqtTrace.Info("TestRequestManager.DiscoverTests: Synchronization context taken"); - this.currentDiscoveryRequest = this.testPlatform.CreateDiscoveryRequest(requestData, criteria, discoveryPayload.TestPlatformOptions); + this.currentDiscoveryRequest = this.testPlatform.CreateDiscoveryRequest( + requestData, + criteria, + discoveryPayload.TestPlatformOptions); discoveryEventsRegistrar?.RegisterDiscoveryEvents(this.currentDiscoveryRequest); - // Notify start of discovery start + // Notify start of discovery start. this.testPlatformEventSource.DiscoveryRequestStart(); - // Start the discovery of tests and wait for completion + // Start the discovery of tests and wait for completion. this.currentDiscoveryRequest.DiscoverAsync(); this.currentDiscoveryRequest.WaitForCompletion(); } @@ -201,7 +233,7 @@ public void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscove { if (this.currentDiscoveryRequest != null) { - // Dispose the discovery request and unregister for events + // Dispose the discovery request and unregister for events. discoveryEventsRegistrar?.UnregisterDiscoveryEvents(currentDiscoveryRequest); this.currentDiscoveryRequest.Dispose(); this.currentDiscoveryRequest = null; @@ -210,21 +242,20 @@ public void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscove EqtTrace.Info("TestRequestManager.DiscoverTests: Discovery tests completed."); this.testPlatformEventSource.DiscoveryRequestStop(); - // Posts the Discovery Complete event. - this.metricsPublisher.Result.PublishMetrics(TelemetryDataConstants.TestDiscoveryCompleteEvent, requestData.MetricsCollection.Metrics); + // Posts the discovery complete event. + this.metricsPublisher.Result.PublishMetrics( + TelemetryDataConstants.TestDiscoveryCompleteEvent, + requestData.MetricsCollection.Metrics); } } } - /// - /// Run Tests with given a set of test cases. - /// - /// TestRun request Payload - /// TestHost Launcher for the run - /// event registrar for run events - /// Protocol related information - /// True, if successful - public void RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLauncher testHostLauncher, ITestRunEventsRegistrar testRunEventsRegistrar, ProtocolConfig protocolConfig) + /// + public void RunTests( + TestRunRequestPayload testRunRequestPayload, + ITestHostLauncher testHostLauncher, + ITestRunEventsRegistrar testRunEventsRegistrar, + ProtocolConfig protocolConfig) { EqtTrace.Info("TestRequestManager.RunTests: run tests started."); @@ -241,14 +272,21 @@ public void RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLaunc // Get sources to auto detect fx and arch for both run selected or run all scenario. var sources = GetSources(testRunRequestPayload); - if (this.UpdateRunSettingsIfRequired(runsettings, sources, testRunEventsRegistrar, out string updatedRunsettings)) + if (this.UpdateRunSettingsIfRequired( + runsettings, + sources, + testRunEventsRegistrar, + out string updatedRunsettings)) { runsettings = updatedRunsettings; } - if (InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings(runsettings)) + if (InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings(runsettings)) { - throw new SettingsException(string.Format(Resources.RunsettingsWithDCErrorMessage, runsettings)); + throw new SettingsException( + string.Format( + Resources.RunsettingsWithDCErrorMessage, + runsettings)); } var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettings); @@ -256,28 +294,34 @@ public void RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLaunc if (requestData.IsTelemetryOptedIn) { - // Collect Metrics + // Collect metrics. this.CollectMetrics(requestData, runConfiguration); - // Collect Commands + // Collect commands. this.LogCommandsTelemetryPoints(requestData); - // Collect data for Legacy Settings + // Collect data for legacy settings. this.LogTelemetryForLegacySettings(requestData, runsettings); } - // get Fakes data collector settings + // Get Fakes data collector settings. if (!string.Equals(Environment.GetEnvironmentVariable("VSTEST_SKIP_FAKES_CONFIGURATION"), "1")) { - // The commandline Options do not have sources in design time mode, - // and so we fall back to using sources instead + // The commandline options do not have sources in design time mode, + // and so we fall back to using sources instead. if (this.commandLineOptions.Sources.Any()) { - GenerateFakesUtilities.GenerateFakesSettings(this.commandLineOptions, this.commandLineOptions.Sources.ToList(), ref runsettings); + GenerateFakesUtilities.GenerateFakesSettings( + this.commandLineOptions, + this.commandLineOptions.Sources.ToList(), + ref runsettings); } else if (sources.Any()) { - GenerateFakesUtilities.GenerateFakesSettings(this.commandLineOptions, sources, ref runsettings); + GenerateFakesUtilities.GenerateFakesSettings( + this.commandLineOptions, + sources, + ref runsettings); } } @@ -291,7 +335,10 @@ public void RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLaunc this.commandLineOptions.TestStatsEventTimeout, testHostLauncher, testRunRequestPayload.TestPlatformOptions?.TestCaseFilter, - testRunRequestPayload.TestPlatformOptions?.FilterOptions); + testRunRequestPayload.TestPlatformOptions?.FilterOptions, + testRunRequestPayload.TestSessionInfo, + debugEnabledForTestSession: testRunRequestPayload.TestSessionInfo != null + && testRunRequestPayload.DebuggingEnabled); } else { @@ -301,13 +348,20 @@ public void RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLaunc testRunRequestPayload.KeepAlive, runsettings, this.commandLineOptions.TestStatsEventTimeout, - testHostLauncher); + testHostLauncher, + testRunRequestPayload.TestSessionInfo, + debugEnabledForTestSession: testRunRequestPayload.TestSessionInfo != null + && testRunRequestPayload.DebuggingEnabled); } - // Run tests + // Run tests. try { - this.RunTests(requestData, runCriteria, testRunEventsRegistrar, testRunRequestPayload.TestPlatformOptions); + this.RunTests( + requestData, + runCriteria, + testRunEventsRegistrar, + testRunRequestPayload.TestPlatformOptions); EqtTrace.Info("TestRequestManager.RunTests: run tests completed."); } finally @@ -315,30 +369,40 @@ public void RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLaunc this.testPlatformEventSource.ExecutionRequestStop(); // Post the run complete event - this.metricsPublisher.Result.PublishMetrics(TelemetryDataConstants.TestExecutionCompleteEvent, requestData.MetricsCollection.Metrics); + this.metricsPublisher.Result.PublishMetrics( + TelemetryDataConstants.TestExecutionCompleteEvent, + requestData.MetricsCollection.Metrics); } } /// - public void ProcessTestRunAttachments(TestRunAttachmentsProcessingPayload attachmentsProcessingPayload, ITestRunAttachmentsProcessingEventsHandler attachmentsProcessingEventsHandler, ProtocolConfig protocolConfig) + public void ProcessTestRunAttachments( + TestRunAttachmentsProcessingPayload attachmentsProcessingPayload, + ITestRunAttachmentsProcessingEventsHandler attachmentsProcessingEventsHandler, + ProtocolConfig protocolConfig) { EqtTrace.Info("TestRequestManager.ProcessTestRunAttachments: Test run attachments processing started."); this.telemetryOptedIn = attachmentsProcessingPayload.CollectMetrics; var requestData = this.GetRequestData(protocolConfig); - // Make sure to run the run request inside a lock as the below section is not thread-safe - // There can be only one discovery, execution or attachments processing request at a given point in time + // Make sure to run the run request inside a lock as the below section is not thread-safe. + // There can be only one discovery, execution or attachments processing request at a given + // point in time. lock (this.syncObject) { try { - EqtTrace.Info("TestRequestManager.ProcessTestRunAttachments: Synchronization context taken"); + EqtTrace.Info("TestRequestManager.ProcessTestRunAttachments: Synchronization context taken."); this.testPlatformEventSource.TestRunAttachmentsProcessingRequestStart(); this.currentAttachmentsProcessingCancellationTokenSource = new CancellationTokenSource(); - Task task = this.attachmentsProcessingManager.ProcessTestRunAttachmentsAsync(requestData, attachmentsProcessingPayload.Attachments, attachmentsProcessingEventsHandler, this.currentAttachmentsProcessingCancellationTokenSource.Token); + Task task = this.attachmentsProcessingManager.ProcessTestRunAttachmentsAsync( + requestData, + attachmentsProcessingPayload.Attachments, + attachmentsProcessingEventsHandler, + this.currentAttachmentsProcessingCancellationTokenSource.Token); task.Wait(); } finally @@ -352,47 +416,116 @@ public void ProcessTestRunAttachments(TestRunAttachmentsProcessingPayload attach EqtTrace.Info("TestRequestManager.ProcessTestRunAttachments: Test run attachments processing completed."); this.testPlatformEventSource.TestRunAttachmentsProcessingRequestStop(); - // Post the attachments processing complete event - this.metricsPublisher.Result.PublishMetrics(TelemetryDataConstants.TestAttachmentsProcessingCompleteEvent, requestData.MetricsCollection.Metrics); + // Post the attachments processing complete event. + this.metricsPublisher.Result.PublishMetrics( + TelemetryDataConstants.TestAttachmentsProcessingCompleteEvent, + requestData.MetricsCollection.Metrics); + } + } + } + + /// + public void StartTestSession( + StartTestSessionPayload payload, + ITestHostLauncher testHostLauncher, + ITestSessionEventsHandler eventsHandler, + ProtocolConfig protocolConfig) + { + EqtTrace.Info("TestRequestManager.StartTestSession: Starting test session."); + + if (payload.TestPlatformOptions != null) + { + this.telemetryOptedIn = payload.TestPlatformOptions.CollectMetrics; + } + + var requestData = this.GetRequestData(protocolConfig); + + if (this.UpdateRunSettingsIfRequired( + payload.RunSettings, + payload.Sources, + null, + out string updatedRunsettings)) + { + payload.RunSettings = updatedRunsettings; + } + + if (InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings(payload.RunSettings)) + { + throw new SettingsException( + string.Format( + Resources.RunsettingsWithDCErrorMessage, + payload.RunSettings)); + } + + // TODO (copoiena): Collect metrics ? + + lock (this.syncObject) + { + try + { + EqtTrace.Info("TestRequestManager.StartTestRunner: Synchronization context taken."); + this.testPlatformEventSource.StartTestSessionStart(); + + var criteria = new StartTestSessionCriteria() + { + Sources = payload.Sources, + RunSettings = payload.RunSettings, + TestHostLauncher = testHostLauncher + }; + + this.testPlatform.StartTestSession(requestData, criteria, eventsHandler); + } + finally + { + EqtTrace.Info("TestRequestManager.StartTestSession: Starting test session completed."); + this.testPlatformEventSource.StartTestSessionStop(); + + // Post the attachments processing complete event. + this.metricsPublisher.Result.PublishMetrics( + TelemetryDataConstants.StartTestSessionCompleteEvent, + requestData.MetricsCollection.Metrics); } } } private void LogTelemetryForLegacySettings(IRequestData requestData, string runsettings) { - requestData.MetricsCollection.Add(TelemetryDataConstants.TestSettingsUsed, InferRunSettingsHelper.IsTestSettingsEnabled(runsettings)); + requestData.MetricsCollection.Add( + TelemetryDataConstants.TestSettingsUsed, + InferRunSettingsHelper.IsTestSettingsEnabled(runsettings)); - if (InferRunSettingsHelper.TryGetLegacySettingElements(runsettings, out Dictionary legacySettingsTelemetry)) + if (InferRunSettingsHelper.TryGetLegacySettingElements( + runsettings, + out Dictionary legacySettingsTelemetry)) { foreach (var ciData in legacySettingsTelemetry) { // We are collecting telemetry for the legacy nodes and attributes used in the runsettings. - requestData.MetricsCollection.Add(string.Format("{0}.{1}", TelemetryDataConstants.LegacySettingPrefix, ciData.Key), ciData.Value); + requestData.MetricsCollection.Add( + string.Format( + "{0}.{1}", + TelemetryDataConstants.LegacySettingPrefix, + ciData.Key), + ciData.Value); } } } - /// - /// Cancel the test run. - /// + /// public void CancelTestRun() { EqtTrace.Info("TestRequestManager.CancelTestRun: Sending cancel request."); this.currentTestRunRequest?.CancelAsync(); } - /// - /// Cancel the test discovery. - /// + /// public void CancelDiscovery() { EqtTrace.Info("TestRequestManager.CancelTestDiscovery: Sending cancel request."); this.currentDiscoveryRequest?.Abort(); } - /// - /// Aborts the test run. - /// + /// public void AbortTestRun() { EqtTrace.Info("TestRequestManager.AbortTestRun: Sending abort request."); @@ -430,28 +563,41 @@ private void Dispose(bool disposing) } } - private bool UpdateRunSettingsIfRequired(string runsettingsXml, List sources, IBaseTestEventsRegistrar registrar, out string updatedRunSettingsXml) + private bool UpdateRunSettingsIfRequired( + string runsettingsXml, + IList sources, + IBaseTestEventsRegistrar registrar, + out string updatedRunSettingsXml) { bool settingsUpdated = false; updatedRunSettingsXml = runsettingsXml; - IDictionary sourcePlatforms = new Dictionary(); - IDictionary sourceFrameworks = new Dictionary(); + var sourcePlatforms = new Dictionary(); + var sourceFrameworks = new Dictionary(); if (!string.IsNullOrEmpty(runsettingsXml)) { // TargetFramework is full CLR. Set DesignMode based on current context. using (var stream = new StringReader(runsettingsXml)) - using (var reader = XmlReader.Create(stream, XmlRunSettingsUtilities.ReaderSettings)) + using (var reader = XmlReader.Create( + stream, + XmlRunSettingsUtilities.ReaderSettings)) { var document = new XmlDocument(); document.Load(reader); var navigator = document.CreateNavigator(); var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettingsXml); - var loggerRunSettings = XmlRunSettingsUtilities.GetLoggerRunSettings(runsettingsXml) ?? new LoggerRunSettings(); - - settingsUpdated |= this.UpdateFramework(document, navigator, sources, sourceFrameworks, registrar, out Framework chosenFramework); - - // Choose default architecture based on the framework + var loggerRunSettings = XmlRunSettingsUtilities.GetLoggerRunSettings(runsettingsXml) + ?? new LoggerRunSettings(); + + settingsUpdated |= this.UpdateFramework( + document, + navigator, + sources, + sourceFrameworks, + registrar, + out Framework chosenFramework); + + // Choose default architecture based on the framework. // For .NET core, the default platform architecture should be based on the process. Architecture defaultArchitecture = Architecture.X86; if (chosenFramework.Name.IndexOf("netstandard", StringComparison.OrdinalIgnoreCase) >= 0 @@ -459,22 +605,37 @@ private bool UpdateRunSettingsIfRequired(string runsettingsXml, List sou || chosenFramework.Name.IndexOf("net5", StringComparison.OrdinalIgnoreCase) >= 0) { #if NETCOREAPP - // We are running in vstest.console that is either started via dotnet.exe or via vstest.console.exe .NET Core - // executable. For AnyCPU dlls this should resolve 32-bit SDK when running from 32-bit dotnet process and + // We are running in vstest.console that is either started via dotnet.exe + // or via vstest.console.exe .NET Core executable. For AnyCPU dlls this + // should resolve 32-bit SDK when running from 32-bit dotnet process and // 64-bit SDK when running from 64-bit dotnet process. defaultArchitecture = Environment.Is64BitProcess ? Architecture.X64 : Architecture.X86; #else - // We are running in vstest.console.exe that was built against .NET Framework. This console prefers 32-bit - // because it needs to run as 32-bit to be compatible with QTAgent. It runs as 32-bit both under VS and - // in Developer console. Set the default architecture based on the OS architecture, to find 64-bit dotnet SDK - // when running AnyCPU dll on 64-bit system, and 32-bit SDK when running AnyCPU dll on 32-bit OS. + // We are running in vstest.console.exe that was built against .NET + // Framework. This console prefers 32-bit because it needs to run as 32-bit + // to be compatible with QTAgent. It runs as 32-bit both under VS and in + // Developer console. Set the default architecture based on the OS + // architecture, to find 64-bit dotnet SDK when running AnyCPU dll on 64-bit + // system, and 32-bit SDK when running AnyCPU dll on 32-bit OS. // We want to find 64-bit SDK because it is more likely to be installed. defaultArchitecture = Environment.Is64BitOperatingSystem ? Architecture.X64 : Architecture.X86; #endif } - settingsUpdated |= this.UpdatePlatform(document, navigator, sources, sourcePlatforms, defaultArchitecture, out Architecture chosenPlatform); - this.CheckSourcesForCompatibility(chosenFramework, chosenPlatform, defaultArchitecture, sourcePlatforms, sourceFrameworks, registrar); + settingsUpdated |= this.UpdatePlatform( + document, + navigator, + sources, + sourcePlatforms, + defaultArchitecture, + out Architecture chosenPlatform); + this.CheckSourcesForCompatibility( + chosenFramework, + chosenPlatform, + defaultArchitecture, + sourcePlatforms, + sourceFrameworks, + registrar); settingsUpdated |= this.UpdateDesignMode(document, runConfiguration); settingsUpdated |= this.UpdateCollectSourceInformation(document, runConfiguration); settingsUpdated |= this.UpdateTargetDevice(navigator, document, runConfiguration); @@ -487,23 +648,33 @@ private bool UpdateRunSettingsIfRequired(string runsettingsXml, List sou return settingsUpdated; } - private bool AddOrUpdateConsoleLogger(XmlDocument document, RunConfiguration runConfiguration, LoggerRunSettings loggerRunSettings) + private bool AddOrUpdateConsoleLogger( + XmlDocument document, + RunConfiguration runConfiguration, + LoggerRunSettings loggerRunSettings) { - // Update console logger settings + // Update console logger settings. bool consoleLoggerUpdated = this.UpdateConsoleLoggerIfExists(document, loggerRunSettings); // In case of CLI, add console logger if not already present. - bool designMode = runConfiguration.DesignModeSet ? runConfiguration.DesignMode : this.commandLineOptions.IsDesignMode; + bool designMode = runConfiguration.DesignModeSet + ? runConfiguration.DesignMode + : this.commandLineOptions.IsDesignMode; if (!designMode && !consoleLoggerUpdated) { this.AddConsoleLogger(document, loggerRunSettings); } - // Update is required 1) in case of CLI 2) in case of design mode if console logger is present in runsettings. + // Update is required: + // 1) in case of CLI; + // 2) in case of design mode if console logger is present in runsettings. return !designMode || consoleLoggerUpdated; } - private bool UpdateTargetDevice(XPathNavigator navigator, XmlDocument document, RunConfiguration runConfiguration) + private bool UpdateTargetDevice( + XPathNavigator navigator, + XmlDocument document, + RunConfiguration runConfiguration) { bool updateRequired = InferRunSettingsHelper.TryGetDeviceXml(navigator, out string deviceXml); if (updateRequired) @@ -513,12 +684,16 @@ private bool UpdateTargetDevice(XPathNavigator navigator, XmlDocument document, return updateRequired; } - private bool UpdateCollectSourceInformation(XmlDocument document, RunConfiguration runConfiguration) + private bool UpdateCollectSourceInformation( + XmlDocument document, + RunConfiguration runConfiguration) { bool updateRequired = !runConfiguration.CollectSourceInformationSet; if (updateRequired) { - InferRunSettingsHelper.UpdateCollectSourceInformation(document, this.commandLineOptions.ShouldCollectSourceInformation); + InferRunSettingsHelper.UpdateCollectSourceInformation( + document, + this.commandLineOptions.ShouldCollectSourceInformation); } return updateRequired; } @@ -529,15 +704,29 @@ private bool UpdateDesignMode(XmlDocument document, RunConfiguration runConfigur bool updateRequired = !runConfiguration.DesignModeSet; if (updateRequired) { - InferRunSettingsHelper.UpdateDesignMode(document, this.commandLineOptions.IsDesignMode); + InferRunSettingsHelper.UpdateDesignMode( + document, + this.commandLineOptions.IsDesignMode); } return updateRequired; } - private void CheckSourcesForCompatibility(Framework chosenFramework, Architecture chosenPlatform, Architecture defaultArchitecture, IDictionary sourcePlatforms, IDictionary sourceFrameworks, IBaseTestEventsRegistrar registrar) + private void CheckSourcesForCompatibility( + Framework chosenFramework, + Architecture chosenPlatform, + Architecture defaultArchitecture, + IDictionary sourcePlatforms, + IDictionary sourceFrameworks, + IBaseTestEventsRegistrar registrar) { - // Find compatible sources - var compatibleSources = InferRunSettingsHelper.FilterCompatibleSources(chosenPlatform, defaultArchitecture, chosenFramework, sourcePlatforms, sourceFrameworks, out var incompatibleSettingWarning); + // Find compatible sources. + var compatibleSources = InferRunSettingsHelper.FilterCompatibleSources( + chosenPlatform, + defaultArchitecture, + chosenFramework, + sourcePlatforms, + sourceFrameworks, + out var incompatibleSettingWarning); // Raise warnings for incompatible sources if (!string.IsNullOrEmpty(incompatibleSettingWarning)) @@ -554,36 +743,59 @@ private void CheckSourcesForCompatibility(Framework chosenFramework, Architectur } } - private bool UpdatePlatform(XmlDocument document, XPathNavigator navigator, List sources, IDictionary sourcePlatforms, Architecture defaultArchitecture, out Architecture chosenPlatform) + private bool UpdatePlatform( + XmlDocument document, + XPathNavigator navigator, + IList sources, + IDictionary sourcePlatforms, + Architecture defaultArchitecture, + out Architecture chosenPlatform) { - // Get platform from sources - var inferedPlatform = inferHelper.AutoDetectArchitecture(sources, sourcePlatforms, defaultArchitecture); + // Get platform from sources. + var inferedPlatform = inferHelper.AutoDetectArchitecture( + sources, + sourcePlatforms, + defaultArchitecture); - // Get platform from runsettings + // Get platform from runsettings. bool updatePlatform = IsAutoPlatformDetectRequired(navigator, out chosenPlatform); - // Update platform if required. For command line scenario update happens in ArgumentProcessor. + // Update platform if required. For command line scenario update happens in + // ArgumentProcessor. if (updatePlatform) { - InferRunSettingsHelper.UpdateTargetPlatform(document, inferedPlatform.ToString(), overwrite: true); + InferRunSettingsHelper.UpdateTargetPlatform( + document, + inferedPlatform.ToString(), + overwrite: true); chosenPlatform = inferedPlatform; } return updatePlatform; } - private bool UpdateFramework(XmlDocument document, XPathNavigator navigator, List sources, IDictionary sourceFrameworks, IBaseTestEventsRegistrar registrar, out Framework chosenFramework) + private bool UpdateFramework( + XmlDocument document, + XPathNavigator navigator, + IList sources, + IDictionary sourceFrameworks, + IBaseTestEventsRegistrar registrar, + out Framework chosenFramework) { - // Get framework from sources + // Get framework from sources. var inferedFramework = inferHelper.AutoDetectFramework(sources, sourceFrameworks); // Get framework from runsettings. bool updateFramework = IsAutoFrameworkDetectRequired(navigator, out chosenFramework); - // Update framework if required. For command line scenario update happens in ArgumentProcessor. + // Update framework if required. For command line scenario update happens in + // ArgumentProcessor. if (updateFramework) { - InferRunSettingsHelper.UpdateTargetFramework(document, inferedFramework?.ToString(), overwrite: true); + InferRunSettingsHelper.UpdateTargetFramework( + document, + inferedFramework?.ToString(), + overwrite: true); chosenFramework = inferedFramework; } @@ -614,7 +826,10 @@ private void AddConsoleLogger(XmlDocument document, LoggerRunSettings loggerRunS }; loggerRunSettings.LoggerSettingsList.Add(consoleLogger); - RunSettingsProviderExtensions.UpdateRunSettingsXmlDocumentInnerXml(document, Constants.LoggerRunSettingsName, loggerRunSettings.ToXml().InnerXml); + RunSettingsProviderExtensions.UpdateRunSettingsXmlDocumentInnerXml( + document, + Constants.LoggerRunSettingsName, + loggerRunSettings.ToXml().InnerXml); } /// @@ -623,7 +838,9 @@ private void AddConsoleLogger(XmlDocument document, LoggerRunSettings loggerRunS /// Runsettings document. /// Logger run settings. /// True if updated console logger in runsettings successfully. - private bool UpdateConsoleLoggerIfExists(XmlDocument document, LoggerRunSettings loggerRunSettings) + private bool UpdateConsoleLoggerIfExists( + XmlDocument document, + LoggerRunSettings loggerRunSettings) { var defaultConsoleLogger = new LoggerSettings { @@ -639,24 +856,36 @@ private bool UpdateConsoleLoggerIfExists(XmlDocument document, LoggerRunSettings var consoleLogger = loggerRunSettings.LoggerSettingsList[existingLoggerIndex]; consoleLogger.AssemblyQualifiedName = typeof(ConsoleLogger).AssemblyQualifiedName; consoleLogger.CodeBase = typeof(ConsoleLogger).GetTypeInfo().Assembly.Location; - RunSettingsProviderExtensions.UpdateRunSettingsXmlDocumentInnerXml(document, Constants.LoggerRunSettingsName, loggerRunSettings.ToXml().InnerXml); + RunSettingsProviderExtensions.UpdateRunSettingsXmlDocumentInnerXml( + document, + Constants.LoggerRunSettingsName, + loggerRunSettings.ToXml().InnerXml); + return true; } return false; } - private void RunTests(IRequestData requestData, TestRunCriteria testRunCriteria, ITestRunEventsRegistrar testRunEventsRegistrar, TestPlatformOptions options) + private void RunTests( + IRequestData requestData, + TestRunCriteria testRunCriteria, + ITestRunEventsRegistrar testRunEventsRegistrar, + TestPlatformOptions options) { - // Make sure to run the run request inside a lock as the below section is not thread-safe - // TranslationLayer can process faster as it directly gets the raw un-serialized messages whereas - // below logic needs to deserialize and do some cleanup - // While this section is cleaning up, TranslationLayer can trigger run causing multiple threads to run the below section at the same time + // Make sure to run the run request inside a lock as the below section is not thread-safe. + // TranslationLayer can process faster as it directly gets the raw un-serialized messages + // whereas below logic needs to deserialize and do some cleanup. + // While this section is cleaning up, TranslationLayer can trigger run causing multiple + // threads to run the below section at the same time. lock (this.syncObject) { try { - this.currentTestRunRequest = this.testPlatform.CreateTestRunRequest(requestData, testRunCriteria, options); + this.currentTestRunRequest = this.testPlatform.CreateTestRunRequest( + requestData, + testRunCriteria, + options); this.testRunResultAggregator.RegisterTestRunEvents(this.currentTestRunRequest); testRunEventsRegistrar?.RegisterTestRunEvents(this.currentTestRunRequest); @@ -688,21 +917,26 @@ private void RunTests(IRequestData requestData, TestRunCriteria testRunCriteria, } } - private bool IsAutoFrameworkDetectRequired(XPathNavigator navigator, out Framework chosenFramework) + private bool IsAutoFrameworkDetectRequired( + XPathNavigator navigator, + out Framework chosenFramework) { bool required = true; chosenFramework = null; if (commandLineOptions.IsDesignMode) { bool isValidFx = - InferRunSettingsHelper.TryGetFrameworkXml(navigator, out var frameworkFromrunsettingsXml); + InferRunSettingsHelper.TryGetFrameworkXml( + navigator, + out var frameworkFromrunsettingsXml); required = !isValidFx || string.IsNullOrWhiteSpace(frameworkFromrunsettingsXml); if (!required) { chosenFramework = Framework.FromString(frameworkFromrunsettingsXml); } } - else if (!commandLineOptions.IsDesignMode && commandLineOptions.FrameworkVersionSpecified) + else if (!commandLineOptions.IsDesignMode + && commandLineOptions.FrameworkVersionSpecified) { required = false; chosenFramework = commandLineOptions.TargetFrameworkVersion; @@ -711,17 +945,24 @@ private bool IsAutoFrameworkDetectRequired(XPathNavigator navigator, out Framewo return required; } - private bool IsAutoPlatformDetectRequired(XPathNavigator navigator, out Architecture chosenPlatform) + private bool IsAutoPlatformDetectRequired( + XPathNavigator navigator, + out Architecture chosenPlatform) { bool required = true; chosenPlatform = Architecture.Default; if (commandLineOptions.IsDesignMode) { - bool isValidPlatform = InferRunSettingsHelper.TryGetPlatformXml(navigator, out var platformXml); + bool isValidPlatform = InferRunSettingsHelper.TryGetPlatformXml( + navigator, + out var platformXml); + required = !isValidPlatform || string.IsNullOrWhiteSpace(platformXml); if (!required) { - chosenPlatform = (Architecture)Enum.Parse(typeof(Architecture), platformXml, true); + chosenPlatform = (Architecture)Enum.Parse( + typeof(Architecture), + platformXml, true); } } else if (!commandLineOptions.IsDesignMode && commandLineOptions.ArchitectureSpecified) @@ -734,45 +975,65 @@ private bool IsAutoPlatformDetectRequired(XPathNavigator navigator, out Architec } /// - /// Collect Metrics + /// Collect metrics. /// - /// Request Data for common Discovery/Execution Services - /// RunConfiguration + /// Request data for common Discovery/Execution services. + /// Run configuration. private void CollectMetrics(IRequestData requestData, RunConfiguration runConfiguration) { // Collecting Target Framework. - requestData.MetricsCollection.Add(TelemetryDataConstants.TargetFramework, runConfiguration.TargetFramework.Name); + requestData.MetricsCollection.Add( + TelemetryDataConstants.TargetFramework, + runConfiguration.TargetFramework.Name); // Collecting Target Platform. - requestData.MetricsCollection.Add(TelemetryDataConstants.TargetPlatform, runConfiguration.TargetPlatform.ToString()); + requestData.MetricsCollection.Add( + TelemetryDataConstants.TargetPlatform, + runConfiguration.TargetPlatform.ToString()); // Collecting Max CPU count. - requestData.MetricsCollection.Add(TelemetryDataConstants.MaxCPUcount, runConfiguration.MaxCpuCount); + requestData.MetricsCollection.Add( + TelemetryDataConstants.MaxCPUcount, + runConfiguration.MaxCpuCount); - // Collecting Target Device. Here, it will be updated run settings so, target device will be under run configuration only. + // Collecting Target Device. Here, it will be updated run settings so, target device + // will be under run configuration only. var targetDevice = runConfiguration.TargetDevice; if (string.IsNullOrEmpty(targetDevice)) { - requestData.MetricsCollection.Add(TelemetryDataConstants.TargetDevice, "Local Machine"); + requestData.MetricsCollection.Add( + TelemetryDataConstants.TargetDevice, + "Local Machine"); } - else if (targetDevice.Equals("Device", StringComparison.Ordinal) || targetDevice.Contains("Emulator")) + else if (targetDevice.Equals("Device", StringComparison.Ordinal) + || targetDevice.Contains("Emulator")) { - requestData.MetricsCollection.Add(TelemetryDataConstants.TargetDevice, targetDevice); + requestData.MetricsCollection.Add( + TelemetryDataConstants.TargetDevice, + targetDevice); } else { - // For IOT scenarios - requestData.MetricsCollection.Add(TelemetryDataConstants.TargetDevice, "Other"); + // For IOT scenarios. + requestData.MetricsCollection.Add( + TelemetryDataConstants.TargetDevice, + "Other"); } - // Collecting TestPlatform Version - requestData.MetricsCollection.Add(TelemetryDataConstants.TestPlatformVersion, Product.Version); + // Collecting TestPlatform version. + requestData.MetricsCollection.Add( + TelemetryDataConstants.TestPlatformVersion, + Product.Version); - // Collecting TargetOS - requestData.MetricsCollection.Add(TelemetryDataConstants.TargetOS, new PlatformEnvironment().OperatingSystemVersion); + // Collecting TargetOS. + requestData.MetricsCollection.Add( + TelemetryDataConstants.TargetOS, + new PlatformEnvironment().OperatingSystemVersion); - //Collecting DisableAppDomain - requestData.MetricsCollection.Add(TelemetryDataConstants.DisableAppDomain, runConfiguration.DisableAppDomain); + //Collecting DisableAppDomain. + requestData.MetricsCollection.Add( + TelemetryDataConstants.DisableAppDomain, + runConfiguration.DisableAppDomain); } @@ -784,7 +1045,8 @@ private void CollectMetrics(IRequestData requestData, RunConfiguration runConfig private static bool IsTelemetryOptedIn() { var telemetryStatus = Environment.GetEnvironmentVariable("VSTEST_TELEMETRY_OPTEDIN"); - return !string.IsNullOrEmpty(telemetryStatus) && telemetryStatus.Equals("1", StringComparison.Ordinal); + return !string.IsNullOrEmpty(telemetryStatus) + && telemetryStatus.Equals("1", StringComparison.Ordinal); } /// @@ -853,14 +1115,16 @@ private void LogCommandsTelemetryPoints(IRequestData requestData) } } - requestData.MetricsCollection.Add(TelemetryDataConstants.CommandLineSwitches, string.Join(",", commandsUsed.ToArray())); + requestData.MetricsCollection.Add( + TelemetryDataConstants.CommandLineSwitches, + string.Join(",", commandsUsed.ToArray())); } /// - /// Gets Request Data + /// Gets request data. /// - /// Protocol Config - /// + /// Protocol config. + /// Request data. private IRequestData GetRequestData(ProtocolConfig protocolConfig) { return new RequestData @@ -877,11 +1141,13 @@ private IRequestData GetRequestData(ProtocolConfig protocolConfig) private List GetSources(TestRunRequestPayload testRunRequestPayload) { List sources = new List(); - if (testRunRequestPayload.Sources != null && testRunRequestPayload.Sources.Count > 0) + if (testRunRequestPayload.Sources != null + && testRunRequestPayload.Sources.Count > 0) { sources = testRunRequestPayload.Sources; } - else if (testRunRequestPayload.TestCases != null && testRunRequestPayload.TestCases.Count > 0) + else if (testRunRequestPayload.TestCases != null + && testRunRequestPayload.TestCases.Count > 0) { ISet sourcesSet = new HashSet(); foreach (var testCase in testRunRequestPayload.TestCases) diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs index 583f3106b9..b39c620579 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs @@ -39,7 +39,7 @@ public class DesignModeClientTests private readonly DesignModeClient designModeClient; - private readonly int protocolVersion = 4; + private readonly int protocolVersion = 5; private readonly AutoResetEvent complateEvent; @@ -133,7 +133,7 @@ public void DesignModeClientConnectShouldNotSendConnectedIfServerConnectionTimes public void DesignModeClientDuringConnectShouldHighestCommonVersionWhenReceivedVersionIsGreaterThanSupportedVersion() { - var verCheck = new Message { MessageType = MessageType.VersionCheck, Payload = 4 }; + var verCheck = new Message { MessageType = MessageType.VersionCheck, Payload = 5 }; var sessionEnd = new Message { MessageType = MessageType.SessionEnd }; this.mockCommunicationManager.Setup(cm => cm.WaitForServerConnection(It.IsAny())).Returns(true); this.mockCommunicationManager.SetupSequence(cm => cm.ReceiveMessage()).Returns(verCheck).Returns(sessionEnd); diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeTestHostLauncherFactoryTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeTestHostLauncherFactoryTests.cs index 79d961f685..177d73d5f1 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeTestHostLauncherFactoryTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeTestHostLauncherFactoryTests.cs @@ -17,7 +17,7 @@ public void DesignModeTestHostFactoryShouldReturnNonDebugLauncherIfDebuggingDisa { var mockDesignModeClient = new Mock(); var testRunRequestPayload = new TestRunRequestPayload { DebuggingEnabled = false }; - var launcher = DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(mockDesignModeClient.Object, testRunRequestPayload); + var launcher = DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(mockDesignModeClient.Object, testRunRequestPayload.DebuggingEnabled); Assert.IsFalse(launcher.IsDebug, "Factory must not return debug launcher if debugging is disabled."); } @@ -27,7 +27,7 @@ public void DesignModeTestHostFactoryShouldReturnDebugLauncherIfDebuggingEnabled { var mockDesignModeClient = new Mock(); var testRunRequestPayload = new TestRunRequestPayload { DebuggingEnabled = true }; - var launcher = DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(mockDesignModeClient.Object, testRunRequestPayload); + var launcher = DesignModeTestHostLauncherFactory.GetCustomHostLauncherForTestRun(mockDesignModeClient.Object, testRunRequestPayload.DebuggingEnabled); Assert.IsTrue(launcher.IsDebug, "Factory must return non-debug launcher if debugging is enabled."); } diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyExecutionManagerWithDataCollectionTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyExecutionManagerWithDataCollectionTests.cs index abfde51160..74a7c9a2b3 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyExecutionManagerWithDataCollectionTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyExecutionManagerWithDataCollectionTests.cs @@ -224,7 +224,7 @@ public TestProcessStartInfo UpdateTestProcessStartInfoWrapper(TestProcessStartIn return this.UpdateTestProcessStartInfo(testProcessStartInfo); } - protected override TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) + public override TestProcessStartInfo UpdateTestProcessStartInfo(TestProcessStartInfo testProcessStartInfo) { return base.UpdateTestProcessStartInfo(testProcessStartInfo); } diff --git a/test/Microsoft.TestPlatform.Utilities.UnitTests/InferRunSettingsHelperTests.cs b/test/Microsoft.TestPlatform.Utilities.UnitTests/InferRunSettingsHelperTests.cs index 6c0a22e6bd..cc3618d49f 100644 --- a/test/Microsoft.TestPlatform.Utilities.UnitTests/InferRunSettingsHelperTests.cs +++ b/test/Microsoft.TestPlatform.Utilities.UnitTests/InferRunSettingsHelperTests.cs @@ -665,9 +665,9 @@ public void RunSettingsWithCodeCoverageAndInlineTestSettingsXml() "; // Act and validate - Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( runSettingsWithCodeCoverageAndInlineTestSettingsXml), "Invalid response"); - Assert.IsTrue(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsTrue(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( ConvertOutOfProcToInProcDataCollectionSettings(runSettingsWithCodeCoverageAndInlineTestSettingsXml)), "Invalid response"); } @@ -698,9 +698,9 @@ public void RunSettingsWithFakesAndCodeCoverageAndInlineTestSettingsXml() "; // Act and validate - Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( runSettingsWithFakesAndCodeCoverageAndInlineTestSettingsXml), "Invalid response"); - Assert.IsTrue(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsTrue(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( ConvertOutOfProcToInProcDataCollectionSettings(runSettingsWithFakesAndCodeCoverageAndInlineTestSettingsXml)), "Invalid response"); } @@ -728,9 +728,9 @@ public void RunSettingsWithEnabledAndDisabledCollectorAndNoEmbeddedTestSettingsX "; // Act and validate - Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( runSettingsWithEnabledAndDisabledCollectorAndInlineTestSettingsXml), "Invalid response"); - Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( ConvertOutOfProcToInProcDataCollectionSettings(runSettingsWithEnabledAndDisabledCollectorAndInlineTestSettingsXml)), "Invalid response"); } @@ -763,9 +763,9 @@ public void RunSettingsWithEnabledAndDisabledCollectorAndInlineTestSettingsXml() "; // Act and validate - Assert.IsTrue(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsTrue(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( runSettingsWithEnabledAndDisabledCollectorAndInlineTestSettingsXml), "Invalid response"); - Assert.IsTrue(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsTrue(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( ConvertOutOfProcToInProcDataCollectionSettings(runSettingsWithEnabledAndDisabledCollectorAndInlineTestSettingsXml)), "Invalid response"); } @@ -798,9 +798,9 @@ public void RunSettingsWithDisabledCollectionSettingsAndInlineTestSettingsXml() "; // Act and validate - Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( runSettingsWithDisabledCollectionSettingsAndInlineTestSettingsXml), "Invalid response"); - Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsInCompatibleWithTestSettings( + Assert.IsFalse(InferRunSettingsHelper.AreRunSettingsCollectorsIncompatibleWithTestSettings( ConvertOutOfProcToInProcDataCollectionSettings(runSettingsWithDisabledCollectionSettingsAndInlineTestSettingsXml)), "Invalid response"); } diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs index 3b2a134a68..828cd0f22c 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs @@ -37,7 +37,7 @@ public class VsTestConsoleRequestSenderTests private readonly int WaitTimeout = 2000; - private int protocolVersion = 4; + private int protocolVersion = 5; private IDataSerializer serializer = JsonDataSerializer.Instance; public VsTestConsoleRequestSenderTests() @@ -743,7 +743,7 @@ public void StartTestRunShouldCompleteWithZeroTests() var runComplete = CreateMessage(MessageType.ExecutionComplete, payload); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); - this.requestSender.StartTestRun(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); + this.requestSender.StartTestRun(new List() { "1.dll" }, null, new TestPlatformOptions(), null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -772,7 +772,7 @@ public async Task StartTestRunAsyncShouldCompleteWithZeroTests() var runComplete = CreateMessage(MessageType.ExecutionComplete, payload); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); - await this.requestSender.StartTestRunAsync(new List() { "1.dll" }, null, null, mockHandler.Object); + await this.requestSender.StartTestRunAsync(new List() { "1.dll" }, null, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -827,7 +827,7 @@ public void StartTestRunShouldCompleteWithSingleTestAndMessage() this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - this.requestSender.StartTestRun(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); + this.requestSender.StartTestRun(new List() { "1.dll" }, null, new TestPlatformOptions(), null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -882,7 +882,7 @@ public async Task StartTestRunAsyncShouldCompleteWithSingleTestAndMessage() this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - await this.requestSender.StartTestRunAsync(new List() { "1.dll" }, null, null, mockHandler.Object); + await this.requestSender.StartTestRunAsync(new List() { "1.dll" }, null, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -904,7 +904,7 @@ public void StartTestRunShouldNotThrowIfTestPlatformOptionsIsNull() Callback((string msg, object requestpayload, int protocol) => { receivedRequest = (TestRunRequestPayload)requestpayload; }); // Act. - this.requestSender.StartTestRun(sources, null, null, mockHandler.Object); + this.requestSender.StartTestRun(sources, null, null, null, mockHandler.Object); // Assert. Assert.IsNotNull(receivedRequest); @@ -927,7 +927,7 @@ public void StartTestRunShouldIncludeFilterInRequestPayload() Callback((string msg, object requestpayload, int protocol) => { receivedRequest = (TestRunRequestPayload)requestpayload; }); // Act. - this.requestSender.StartTestRun(sources, null, new TestPlatformOptions() { TestCaseFilter = filter }, mockHandler.Object); + this.requestSender.StartTestRun(sources, null, new TestPlatformOptions() { TestCaseFilter = filter }, null, mockHandler.Object); // Assert. Assert.IsNotNull(receivedRequest); @@ -990,7 +990,7 @@ public void StartTestRunWithCustomHostShouldComplete() this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runprocessInfoPayload)); - this.requestSender.StartTestRunWithCustomHost(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object, mockLauncher.Object); + this.requestSender.StartTestRunWithCustomHost(new List() { "1.dll" }, null, new TestPlatformOptions(), null, mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1054,7 +1054,7 @@ public async Task StartTestRunAsyncWithCustomHostShouldComplete() this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runprocessInfoPayload)); - await this.requestSender.StartTestRunWithCustomHostAsync(new List() { "1.dll" }, null, null, mockHandler.Object, mockLauncher.Object); + await this.requestSender.StartTestRunWithCustomHostAsync(new List() { "1.dll" }, null, null, null, mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1106,7 +1106,7 @@ public void StartTestRunWithCustomHostShouldNotAbortAndSendErrorToVstestConsoleI this.mockCommunicationManager.Setup(cm => cm.SendMessage(It.IsAny(), It.IsAny(), this.protocolVersion)). Callback(() => this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete))); - this.requestSender.StartTestRunWithCustomHost(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object, mockLauncher.Object); + this.requestSender.StartTestRunWithCustomHost(new List() { "1.dll" }, null, new TestPlatformOptions(), null, mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1155,7 +1155,7 @@ public async Task StartTestRunAsyncWithCustomHostShouldNotAbortAndSendErrorToVst this.mockCommunicationManager.Setup(cm => cm.SendMessage(It.IsAny(), It.IsAny(), this.protocolVersion)). Callback(() => this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete))); - await this.requestSender.StartTestRunWithCustomHostAsync(new List() { "1.dll" }, null, null, mockHandler.Object, mockLauncher.Object); + await this.requestSender.StartTestRunWithCustomHostAsync(new List() { "1.dll" }, null, null, null, mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1175,7 +1175,7 @@ public void StartTestRunWithCustomHostShouldNotThrowIfTestPlatformOptionsIsNull( Callback((string msg, object requestpayload, int protocol) => { receivedRequest = (TestRunRequestPayload)requestpayload; }); // Act. - this.requestSender.StartTestRunWithCustomHost(sources, null, null, mockHandler.Object, new Mock().Object); + this.requestSender.StartTestRunWithCustomHost(sources, null, null, null, mockHandler.Object, new Mock().Object); // Assert. Assert.IsNotNull(receivedRequest); @@ -1198,7 +1198,7 @@ public void StartTestRunWithCustomHostShouldIncludeFilterInRequestPayload() Callback((string msg, object requestpayload, int protocol) => { receivedRequest = (TestRunRequestPayload)requestpayload; }); // Act. - this.requestSender.StartTestRunWithCustomHost(sources, null, new TestPlatformOptions() { TestCaseFilter = filter }, mockHandler.Object, new Mock().Object); + this.requestSender.StartTestRunWithCustomHost(sources, null, new TestPlatformOptions() { TestCaseFilter = filter }, null, mockHandler.Object, new Mock().Object); // Assert. Assert.IsNotNull(receivedRequest); @@ -1225,7 +1225,7 @@ public void StartTestRunWithSelectedTestsShouldCompleteWithZeroTests() var runComplete = CreateMessage(MessageType.ExecutionComplete, payload); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); - this.requestSender.StartTestRun(new List(), null, new TestPlatformOptions(), mockHandler.Object); + this.requestSender.StartTestRun(new List(), null, new TestPlatformOptions(), null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1252,7 +1252,7 @@ public async Task StartTestRunAsyncWithSelectedTestsShouldCompleteWithZeroTests( var runComplete = CreateMessage(MessageType.ExecutionComplete, payload); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); - await this.requestSender.StartTestRunAsync(new List(), null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.StartTestRunAsync(new List(), null, new TestPlatformOptions(), null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1306,7 +1306,7 @@ public void StartTestRunWithSelectedTestsShouldCompleteWithSingleTestAndMessage( this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - this.requestSender.StartTestRun(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + this.requestSender.StartTestRun(testCaseList, null, new TestPlatformOptions(), null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1360,7 +1360,7 @@ public async Task StartTestRunAsyncWithSelectedTestsShouldCompleteWithSingleTest this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1412,7 +1412,7 @@ public void StartTestRunWithSelectedTestsHavingTraitsShouldReturnTestRunComplete receivedChangeEventArgs = stats; }); - this.requestSender.StartTestRun(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + this.requestSender.StartTestRun(testCaseList, null, new TestPlatformOptions(), null, mockHandler.Object); Assert.IsNotNull(receivedChangeEventArgs); Assert.IsTrue(receivedChangeEventArgs.NewTestResults.Count() > 0); @@ -1468,7 +1468,7 @@ public async Task StartTestRunAsyncWithSelectedTestsHavingTraitsShouldReturnTest receivedChangeEventArgs = stats; }); - await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), null, mockHandler.Object); Assert.IsNotNull(receivedChangeEventArgs); Assert.IsTrue(receivedChangeEventArgs.NewTestResults.Count() > 0); @@ -1525,7 +1525,7 @@ public void StartTestRunWithSelectedTestsHavingTraitsShouldReturnTestRunStatsWit this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - this.requestSender.StartTestRun(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + this.requestSender.StartTestRun(testCaseList, null, new TestPlatformOptions(), null, mockHandler.Object); Assert.IsNotNull(receivedChangeEventArgs); Assert.IsTrue(receivedChangeEventArgs.NewTestResults.Any()); @@ -1582,7 +1582,7 @@ public async Task StartTestRunAsyncWithSelectedTestsHavingTraitsShouldReturnTest this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), null, mockHandler.Object); Assert.IsNotNull(receivedChangeEventArgs); Assert.IsTrue(receivedChangeEventArgs.NewTestResults.Any()); @@ -1647,7 +1647,7 @@ public void StartTestRunWithCustomHostWithSelectedTestsComplete() this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runprocessInfoPayload)); - this.requestSender.StartTestRunWithCustomHost(testCaseList, null, new TestPlatformOptions(), mockHandler.Object, mockLauncher.Object); + this.requestSender.StartTestRunWithCustomHost(testCaseList, null, new TestPlatformOptions(), null, mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1709,7 +1709,7 @@ public async Task StartTestRunWithCustomHostAsyncWithSelectedTestsShouldComplete this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runprocessInfoPayload)); - await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object, mockLauncher.Object); + await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, null, new TestPlatformOptions(), null, mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1752,7 +1752,7 @@ public void StartTestRunWithCustomHostInParallelShouldCallCustomHostMultipleTime } }); this.requestSender.InitializeCommunication(); - this.requestSender.StartTestRunWithCustomHost(sources, null, new TestPlatformOptions(), mockHandler.Object, mockLauncher.Object); + this.requestSender.StartTestRunWithCustomHost(sources, null, new TestPlatformOptions(), null, mockHandler.Object, mockLauncher.Object); mockLauncher.Verify(ml => ml.LaunchTestHost(It.IsAny()), Times.Exactly(2)); } @@ -1792,7 +1792,7 @@ public async Task StartTestRunWithCustomHostAsyncInParallelShouldCallCustomHostM }); await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); - await this.requestSender.StartTestRunWithCustomHostAsync(sources, null, null, mockHandler.Object, mockLauncher.Object); + await this.requestSender.StartTestRunWithCustomHostAsync(sources, null, null, null, mockHandler.Object, mockLauncher.Object); mockLauncher.Verify(ml => ml.LaunchTestHost(It.IsAny()), Times.Exactly(2)); } @@ -1807,7 +1807,7 @@ public void StartTestRunShouldAbortOnExceptionInSendMessage() this.mockCommunicationManager.Setup(cm => cm.SendMessage(MessageType.TestRunAllSourcesWithDefaultHost, payload, this.protocolVersion)).Throws(exception); - this.requestSender.StartTestRun(sources, null, new TestPlatformOptions(), mockHandler.Object); + this.requestSender.StartTestRun(sources, null, new TestPlatformOptions(), null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), null, null, null), Times.Once, "Test Run Complete must be called"); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once, "TestMessage event must be called"); @@ -1824,7 +1824,7 @@ public async Task StartTestRunAsyncShouldAbortOnExceptionInSendMessage() this.mockCommunicationManager.Setup(cm => cm.SendMessage(MessageType.TestRunAllSourcesWithDefaultHost, payload, this.protocolVersion)).Throws(exception); - await this.requestSender.StartTestRunAsync(sources, null, null, mockHandler.Object); + await this.requestSender.StartTestRunAsync(sources, null, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), null, null, null), Times.Once, "Test Run Complete must be called"); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once, "TestMessage event must be called"); @@ -1857,7 +1857,7 @@ public void StartTestRunShouldLogErrorOnProcessExited() mockHandler.Setup(mh => mh.HandleTestRunComplete(It.IsAny(), null, null, null)).Callback(() => manualEvent.Set()); - this.requestSender.StartTestRun(sources, null, new TestPlatformOptions(), mockHandler.Object); + this.requestSender.StartTestRun(sources, null, new TestPlatformOptions(), null, mockHandler.Object); manualEvent.WaitOne(); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once); @@ -1886,7 +1886,7 @@ public async Task StartTestRunAsyncShouldLogErrorOnProcessExited() Assert.IsTrue(c.IsCancellationRequested); }).Returns(Task.FromResult((Message)null)); - await this.requestSender.StartTestRunAsync(sources, null, null, mockHandler.Object); + await this.requestSender.StartTestRunAsync(sources, null, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once); } diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperAsyncTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperAsyncTests.cs index fed30c3eb9..be3777ccb8 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperAsyncTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperAsyncTests.cs @@ -182,7 +182,7 @@ public async Task RunTestsAsyncWithSourcesShouldSucceed() { await this.consoleWrapper.RunTestsAsync(this.testSources, "RunSettings", new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testSources, "RunSettings", null, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testSources, "RunSettings", null, null, It.IsAny()), Times.Once); } @@ -191,7 +191,7 @@ public async Task RunTestsAsyncWithSourcesAndNullOptionsShouldSucceedOnNullOptio { await this.consoleWrapper.RunTestsAsync(this.testSources, "RunSettings", null, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testSources, "RunSettings", null, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testSources, "RunSettings", null, null, It.IsAny()), Times.Once); } @@ -201,7 +201,7 @@ public async Task RunTestsAsyncWithSourcesAndOptionsShouldSucceedOnOptions() var options = new TestPlatformOptions(); await this.consoleWrapper.RunTestsAsync(this.testSources, "RunSettings", options, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testSources, "RunSettings", options, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testSources, "RunSettings", options, null, It.IsAny()), Times.Once); } [TestMethod] @@ -213,7 +213,7 @@ await this.consoleWrapper.RunTestsWithCustomTestHostAsync( new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testSources, "RunSettings", null, It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testSources, "RunSettings", null, null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] @@ -226,7 +226,7 @@ await this.consoleWrapper.RunTestsWithCustomTestHostAsync( new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testSources, "RunSettings", null, It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testSources, "RunSettings", null, null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] @@ -241,7 +241,7 @@ await this.consoleWrapper.RunTestsWithCustomTestHostAsync( new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testSources, "RunSettings", options, It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testSources, "RunSettings", options, null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] @@ -249,7 +249,7 @@ public async Task RunTestsAsyncWithSelectedTestsShouldSucceed() { await this.consoleWrapper.RunTestsAsync(this.testCases, "RunSettings", new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testCases, "RunSettings", It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testCases, "RunSettings", It.IsAny(), null, It.IsAny()), Times.Once); } [TestMethod] @@ -257,7 +257,7 @@ public async Task RunTestsAsyncWithSelectedTestsAndOptionsShouldSucceedOnNullOpt { await this.consoleWrapper.RunTestsAsync(this.testCases, "RunSettings", null, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testCases, "RunSettings", null, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testCases, "RunSettings", null, null, It.IsAny()), Times.Once); } [TestMethod] @@ -267,7 +267,7 @@ public async Task RunTestsAsyncWithSelectedTestsAndOptionsShouldSucceedOnOptions await this.consoleWrapper.RunTestsAsync(this.testCases, "RunSettings", options, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testCases, "RunSettings", options, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunAsync(this.testCases, "RunSettings", options, null, It.IsAny()), Times.Once); } [TestMethod] @@ -279,7 +279,7 @@ await this.consoleWrapper.RunTestsWithCustomTestHostAsync( new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testCases, "RunSettings", It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testCases, "RunSettings", It.IsAny(), null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] @@ -292,7 +292,7 @@ await this.consoleWrapper.RunTestsWithCustomTestHostAsync( new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testCases, "RunSettings", null, It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testCases, "RunSettings", null, null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] @@ -306,7 +306,7 @@ await this.consoleWrapper.RunTestsWithCustomTestHostAsync( new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testCases, "RunSettings", options, It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHostAsync(this.testCases, "RunSettings", options, null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs index ee9c0f6a23..caedfbd902 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs @@ -180,7 +180,7 @@ public void RunTestsWithSourcesShouldSucceed() { this.consoleWrapper.RunTests(this.testSources, "RunSettings", new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testSources, "RunSettings", It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testSources, "RunSettings", It.IsAny(), null, It.IsAny()), Times.Once); } [TestMethod] @@ -192,7 +192,7 @@ public void RunTestsWithSourcesAndNullOptionsShouldPassOnNullOptions() null, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testSources, "RunSettings", null, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testSources, "RunSettings", null, null, It.IsAny()), Times.Once); } [TestMethod] @@ -205,7 +205,7 @@ public void RunTestsWithSourcesAndOptionsShouldPassOnOptions() options, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testSources, "RunSettings", options, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testSources, "RunSettings", options, null, It.IsAny()), Times.Once); } [TestMethod] @@ -217,7 +217,7 @@ public void RunTestsWithSourcesAndCustomHostShouldSucceed() new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHost(this.testSources, "RunSettings", It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHost(this.testSources, "RunSettings", It.IsAny(), null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] @@ -236,6 +236,7 @@ public void RunTestsWithSourcesAndOptionsUsingACustomHostShouldPassOnOptions() this.testSources, "RunSettings", options, + null, It.IsAny(), It.IsAny()), Times.Once); @@ -246,7 +247,7 @@ public void RunTestsWithSelectedTestsShouldSucceed() { this.consoleWrapper.RunTests(this.testCases, "RunSettings", new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testCases, "RunSettings", It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testCases, "RunSettings", It.IsAny(), null, It.IsAny()), Times.Once); } [TestMethod] @@ -254,7 +255,7 @@ public void RunTestsWithSelectedTestsAndNullOptionsShouldPassOnNullOptions() { this.consoleWrapper.RunTests(this.testCases, "RunSettings", null, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testCases, "RunSettings", null, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testCases, "RunSettings", null, null, It.IsAny()), Times.Once); } [TestMethod] @@ -264,7 +265,7 @@ public void RunTestsWithSelectedTestsAndOptionsShouldPassOnOptions() this.consoleWrapper.RunTests(this.testCases, "RunSettings", options, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testCases, "RunSettings", options, It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRun(this.testCases, "RunSettings", options, null, It.IsAny()), Times.Once); } [TestMethod] @@ -276,7 +277,7 @@ public void RunTestsWithSelectedTestsAndCustomLauncherShouldSucceed() new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHost(this.testCases, "RunSettings", It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHost(this.testCases, "RunSettings", It.IsAny(), null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] @@ -289,7 +290,7 @@ public void RunTestsWithSelectedTestsAndNullOptionsUsingACustomHostShouldPassOnN new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHost(this.testCases, "RunSettings", null, It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHost(this.testCases, "RunSettings", null, null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] @@ -304,7 +305,7 @@ public void RunTestsWithSelectedTestsAndOptionsUsingACustomHostShouldPassOnOptio new Mock().Object, new Mock().Object); - this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHost(this.testCases, "RunSettings", options, It.IsAny(), It.IsAny()), Times.Once); + this.mockRequestSender.Verify(rs => rs.StartTestRunWithCustomHost(this.testCases, "RunSettings", options, null, It.IsAny(), It.IsAny()), Times.Once); } [TestMethod] diff --git a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs index e8f7ba2a30..76e5d1ac92 100644 --- a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs +++ b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs @@ -235,7 +235,7 @@ public void DiscoverTestsShouldPassSameProtocolConfigInRequestData() RunSettings = DefaultRunsettings }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); @@ -259,7 +259,7 @@ public void DiscoverTestsShouldPassSameProtocolConfigInRequestData() this.testRequestManager.DiscoverTests(payload, mockDiscoveryRegistrar.Object, mockProtocolConfig); // Verify. - Assert.AreEqual(4, actualRequestData.ProtocolConfig.Version); + Assert.AreEqual(5, actualRequestData.ProtocolConfig.Version); } @@ -285,7 +285,7 @@ public void DiscoverTestsShouldCollectMetrics() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -335,7 +335,7 @@ public void DiscoverTestsShouldCollectTargetDeviceLocalMachineIfTargetDeviceStri " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -379,7 +379,7 @@ public void DiscoverTestsShouldCollectTargetDeviceIfTargetDeviceIsDevice() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -423,7 +423,7 @@ public void DiscoverTestsShouldCollectTargetDeviceIfTargetDeviceIsEmulator() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -467,7 +467,7 @@ public void DiscoverTestsShouldCollectCommands() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -523,7 +523,7 @@ public void DiscoverTestsShouldCollectTestSettings() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -571,7 +571,7 @@ public void DiscoverTestsShouldCollectVsmdiFile() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -619,7 +619,7 @@ public void DiscoverTestsShouldCollectTestRunConfigFile() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -914,7 +914,7 @@ public void RunTestsShouldPassSameProtocolConfigInRequestData() Sources = new List() { "a" }, RunSettings = DefaultRunsettings }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( @@ -927,7 +927,7 @@ public void RunTestsShouldPassSameProtocolConfigInRequestData() this.testRequestManager.RunTests(payload, new Mock().Object, new Mock().Object, mockProtocolConfig); // Verify. - Assert.AreEqual(4, actualRequestData.ProtocolConfig.Version); + Assert.AreEqual(5, actualRequestData.ProtocolConfig.Version); } [TestMethod] @@ -941,7 +941,7 @@ public void RunTestsShouldCollectCommands() Sources = new List() { "a" }, RunSettings = DefaultRunsettings }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( @@ -1009,7 +1009,7 @@ public void RunTestsShouldCollectTelemetryForLegacySettings() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( @@ -1059,7 +1059,7 @@ public void RunTestsShouldCollectTelemetryForTestSettingsEmbeddedInsideRunSettin " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( @@ -1107,7 +1107,7 @@ public void RunTestsShouldCollectMetrics() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 4 }; + var mockProtocolConfig = new ProtocolConfig { Version = 5 }; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( From 57c4e48042efec946a993ef31b609f296fb7279c Mon Sep 17 00:00:00 2001 From: Medeni Baykal <433724+Haplois@users.noreply.github.com> Date: Mon, 14 Dec 2020 19:17:29 +0100 Subject: [PATCH 08/46] Removed TypesToLoadAttribute from ObjectModel. (#2674) * Removed TypesToLoadAttribute from ObjectModel, and moved the functionallity into adapters themselves. --- TestPlatform.sln | 35 +++++++--------- ...atform.Extensions.EventLogCollector.csproj | 3 -- .../Properties/AssemblyInfo.cs | 1 - .../Properties/TypesToLoadAttribute.cs | 25 +++++++++++ .../Properties}/TypesToLoadAttribute.cs | 15 ++++--- .../TestPluginDiscoverer.cs | 14 +++---- .../ExtensionFramework/TestPluginManager.cs | 1 - src/Microsoft.TestPlatform.Common/Friends.cs | 2 +- .../Utilities/TypesToLoadUtilities.cs | 42 +++++++++++++++++++ .../Properties/AssemblyInfo.cs | 3 -- .../Properties/TypesToLoadAttribute.cs | 26 ++++++++++++ .../Properties/AssemblyInfo.cs | 4 -- .../Properties/TypesToLoadAttribute.cs | 25 +++++++++++ .../Properties/AssemblyInfo.cs | 3 +- .../Properties/TypesToLoadAttribute.cs | 25 +++++++++++ .../Utilities/AssemblyHelper.cs | 23 +++++++--- .../Properties/AssemblyInfo.cs | 3 -- .../Properties/TypesToLoadAttribute.cs | 25 +++++++++++ src/testhost.x86/testhost.x86.csproj | 1 + src/testhost/testhost.csproj | 1 + .../DiscoveryTests.cs | 32 ++++++++++++++ .../IntegrationTestEnvironment.cs | 6 ++- 22 files changed, 256 insertions(+), 59 deletions(-) create mode 100644 src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/TypesToLoadAttribute.cs rename src/{Microsoft.TestPlatform.ObjectModel/Utilities => DataCollectors/TraceDataCollector/Properties}/TypesToLoadAttribute.cs (68%) create mode 100644 src/Microsoft.TestPlatform.Common/Utilities/TypesToLoadUtilities.cs create mode 100644 src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/TypesToLoadAttribute.cs create mode 100644 src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/TypesToLoadAttribute.cs create mode 100644 src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/TypesToLoadAttribute.cs create mode 100644 src/Microsoft.TestPlatform.TestHostProvider/Properties/TypesToLoadAttribute.cs diff --git a/TestPlatform.sln b/TestPlatform.sln index 26a8b21bb6..4150d781ae 100644 --- a/TestPlatform.sln +++ b/TestPlatform.sln @@ -15,7 +15,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "datacollector", "src\dataco EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Build", "src\Microsoft.TestPlatform.Build\Microsoft.TestPlatform.Build.csproj", "{6F5EC38C-4A11-40D3-827C-F607B90BEFF0}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Logger", "Logger", "{5E7F18A8-F843-4C8A-AB02-4C7D9205C6CF}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Loggers", "Loggers", "{5E7F18A8-F843-4C8A-AB02-4C7D9205C6CF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Client", "src\Microsoft.TestPlatform.Client\Microsoft.TestPlatform.Client.csproj", "{E19B5128-3469-492E-82E1-725631C4A68C}" EndProject @@ -41,10 +41,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vstest.console", "src\vstes EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Integration", "Integration", "{46250E12-4CF1-4051-B4A7-80C8C06E0068}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Logger", "Logger", "{020E15EA-731F-4667-95AF-226671E0C3AE}" - ProjectSection(SolutionItems) = preProject - test\Microsoft.TestPlatform.AcceptanceTests\TestResults.html = test\Microsoft.TestPlatform.AcceptanceTests\TestResults.html - EndProjectSection +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Loggers", "Loggers", "{020E15EA-731F-4667-95AF-226671E0C3AE}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Performance", "Performance", "{595BE9C1-E10F-4E50-938A-E6C248D3F950}" EndProject @@ -800,17 +797,17 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {50C00046-0DA3-4B5C-9F6F-7BE1145E156A} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} - {01409D95-A5F1-4EBE-94B1-909D5D2D0DC3} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} + {50C00046-0DA3-4B5C-9F6F-7BE1145E156A} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} + {01409D95-A5F1-4EBE-94B1-909D5D2D0DC3} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} {2C7CE1F8-E73E-4987-8023-B5A0EBAC86E8} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {6F5EC38C-4A11-40D3-827C-F607B90BEFF0} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {5E7F18A8-F843-4C8A-AB02-4C7D9205C6CF} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {E19B5128-3469-492E-82E1-725631C4A68C} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} - {68ADC720-316E-4895-9F8E-C3CCADD262BE} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} - {1621415E-7723-4F46-A589-4C4620C0751A} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} - {987898D9-724E-4324-BF91-77B1A6DBE8F1} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} - {FD63F778-3938-45D2-900B-51EC770F70E5} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} - {61F7F446-9EF3-4768-B33A-4D75F60E1059} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} + {68ADC720-316E-4895-9F8E-C3CCADD262BE} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} + {1621415E-7723-4F46-A589-4C4620C0751A} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} + {987898D9-724E-4324-BF91-77B1A6DBE8F1} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} + {FD63F778-3938-45D2-900B-51EC770F70E5} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} + {61F7F446-9EF3-4768-B33A-4D75F60E1059} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} {D5296435-3A3F-4B1A-81D1-434EC9E97DEF} = {5E7F18A8-F843-4C8A-AB02-4C7D9205C6CF} {790B8030-00C2-4121-B125-EDC4CE329BA3} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {27DFBD04-64B2-4F1B-82B2-006620CCA6F8} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} @@ -820,12 +817,12 @@ Global {020E15EA-731F-4667-95AF-226671E0C3AE} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {595BE9C1-E10F-4E50-938A-E6C248D3F950} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {0D59BA81-6279-4650-AEBB-4EA735C28A1A} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} - {DE730F17-7D5C-4D9D-B479-025024BF4F1D} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} - {E062FFD6-DEB1-4DB4-8B6E-ADBF04129545} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} - {F582949D-8B92-47BD-9DD7-9F2BFCCC290C} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} - {376A7588-50DF-46CD-955B-0309F491D830} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} + {DE730F17-7D5C-4D9D-B479-025024BF4F1D} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} + {E062FFD6-DEB1-4DB4-8B6E-ADBF04129545} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} + {F582949D-8B92-47BD-9DD7-9F2BFCCC290C} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} + {376A7588-50DF-46CD-955B-0309F491D830} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} {5DF3CF65-3E11-4639-964D-7BEB4109DCF9} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} - {D3E8A13B-92EE-45A8-BB24-40EC3CC9DB34} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} + {D3E8A13B-92EE-45A8-BB24-40EC3CC9DB34} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} {9EFCEFB5-253E-4DE2-8A70-821D7B8189DF} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {3A8080FB-9C93-45B9-8EB5-828DDC31FDF0} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {BFF7714C-E5A3-4EEB-B04B-5FA47F29AD03} = {020E15EA-731F-4667-95AF-226671E0C3AE} @@ -847,7 +844,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} + {76D4BB7E-D981-42D5-BE96-6FAD8DEF9A4A} = {B705537C-B82C-4A30-AFA5-6244D9A7DAEB} {488675EC-C8BB-40E0-AD4F-91F623D548B3} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {B705537C-B82C-4A30-AFA5-6244D9A7DAEB} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {65A25D6E-C9CC-4F45-8925-04087AC82634} = {B705537C-B82C-4A30-AFA5-6244D9A7DAEB} @@ -862,7 +859,7 @@ Global {E7D4921C-F12D-4E1C-85AC-8B7F91C59B0E} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {236A71E3-01DA-4679-9DFF-16A8E079ACFF} = {5E7F18A8-F843-4C8A-AB02-4C7D9205C6CF} {41248B96-6E15-4E5E-A78F-859897676814} = {020E15EA-731F-4667-95AF-226671E0C3AE} - {074F5BD6-DC05-460B-B78F-044D125FD787} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} + {074F5BD6-DC05-460B-B78F-044D125FD787} = {D9A30E32-D466-4EC5-B4F2-62E17562279B} {DCD0C39E-C78C-4A44-B0BD-7325254A2E97} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Microsoft.TestPlatform.Extensions.EventLogCollector.csproj b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Microsoft.TestPlatform.Extensions.EventLogCollector.csproj index a86a2ef4b3..61c74ab8c2 100644 --- a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Microsoft.TestPlatform.Extensions.EventLogCollector.csproj +++ b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Microsoft.TestPlatform.Extensions.EventLogCollector.csproj @@ -29,9 +29,6 @@ - - - True diff --git a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/AssemblyInfo.cs b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/AssemblyInfo.cs index dd4512dc14..e0e2c84b82 100644 --- a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/AssemblyInfo.cs +++ b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/AssemblyInfo.cs @@ -14,7 +14,6 @@ [assembly: AssemblyCopyright(" Microsoft Corporation. All rights reserved.")] [assembly: AssemblyProduct("Microsoft.TestPlatform.Extensions.EventLogCollector")] [assembly: AssemblyTrademark("")] -[assembly: TypesToLoad(typeof(EventLogDataCollector))] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from diff --git a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/TypesToLoadAttribute.cs b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/TypesToLoadAttribute.cs new file mode 100644 index 0000000000..0869251ec9 --- /dev/null +++ b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/TypesToLoadAttribute.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. + +using System; +using Microsoft.TestPlatform.Extensions.EventLogCollector; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + +[assembly: TypesToLoad(typeof(EventLogDataCollector))] + +namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities +{ + /// + /// Custom Attribute to specify the exact types which should be loaded from assembly + /// + [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] + internal sealed class TypesToLoadAttribute : Attribute + { + public TypesToLoadAttribute(params Type[] types) + { + this.Types = types; + } + + public Type[] Types { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Utilities/TypesToLoadAttribute.cs b/src/DataCollectors/TraceDataCollector/Properties/TypesToLoadAttribute.cs similarity index 68% rename from src/Microsoft.TestPlatform.ObjectModel/Utilities/TypesToLoadAttribute.cs rename to src/DataCollectors/TraceDataCollector/Properties/TypesToLoadAttribute.cs index 5f8824b510..48cad540f0 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Utilities/TypesToLoadAttribute.cs +++ b/src/DataCollectors/TraceDataCollector/Properties/TypesToLoadAttribute.cs @@ -1,22 +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. +using System; +using Microsoft.VisualStudio.Coverage; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + +[assembly: TypesToLoad(typeof(DynamicCoverageDataCollector))] + namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities { - using System; - /// /// Custom Attribute to specify the exact types which should be loaded from assembly /// [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] - [CLSCompliant(false)] - public sealed class TypesToLoadAttribute : Attribute + internal sealed class TypesToLoadAttribute : Attribute { public TypesToLoadAttribute(params Type[] types) { - Types = types; + this.Types = types; } public Type[] Types { get; } } -} +} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginDiscoverer.cs b/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginDiscoverer.cs index 3d845df33a..f08f565394 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginDiscoverer.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginDiscoverer.cs @@ -18,6 +18,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using CommonResources = Resources.Resources; + using Microsoft.VisualStudio.TestPlatform.Common.Utilities; /// /// Discovers test extensions in a directory. @@ -108,8 +109,6 @@ private void AddKnownExtensions(ref IEnumerable extensionPaths) /// /// Test plugins collection to add to. /// - [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We would like to continue discovering all plugins even if some dll in Extensions folder is not able to be load properly")] private void GetTestExtensionsFromFiles( string[] files, Dictionary pluginInfos) where TPluginInfo : TestPluginInformation @@ -167,13 +166,10 @@ private void GetTestExtensionsFromAssembly(Assembly ass Type extension = typeof(TExtension); try - { - var customAttribute = CustomAttributeExtensions.GetCustomAttribute(assembly, typeof(TypesToLoadAttribute)) as TypesToLoadAttribute; - if (customAttribute != null) - { - types = customAttribute.Types; - } - else + { + types = TypesToLoadUtilities.GetTypesToLoad(assembly); + + if (!types.Any()) { types = assembly.GetTypes().Where(type => type.GetTypeInfo().IsClass && !type.GetTypeInfo().IsAbstract); } diff --git a/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginManager.cs b/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginManager.cs index ae780aa7a3..b322d75fd7 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginManager.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginManager.cs @@ -5,7 +5,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Reflection; using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework.Utilities; diff --git a/src/Microsoft.TestPlatform.Common/Friends.cs b/src/Microsoft.TestPlatform.Common/Friends.cs index e767fb98ad..fb645969e2 100644 --- a/src/Microsoft.TestPlatform.Common/Friends.cs +++ b/src/Microsoft.TestPlatform.Common/Friends.cs @@ -24,5 +24,5 @@ [assembly: InternalsVisibleTo("Microsoft.TestPlatform.Client.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.TestPlatform.TestUtilities, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] - +[assembly: InternalsVisibleTo("Microsoft.TestPlatform.AcceptanceTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] #endregion \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Utilities/TypesToLoadUtilities.cs b/src/Microsoft.TestPlatform.Common/Utilities/TypesToLoadUtilities.cs new file mode 100644 index 0000000000..fb25c588ff --- /dev/null +++ b/src/Microsoft.TestPlatform.Common/Utilities/TypesToLoadUtilities.cs @@ -0,0 +1,42 @@ +// 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.Common.Utilities +{ + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + + using System; + using System.Collections.Generic; + using System.Reflection; + using System.Linq; + + internal static class TypesToLoadUtilities + { + public const string TypesToLoadAttributeFullName = "Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities.TypesToLoadAttribute"; + + internal static IEnumerable GetTypesToLoad(Assembly assembly) + { + ValidateArg.NotNull(assembly, nameof(assembly)); + + var typesToLoad = assembly + .GetCustomAttributes(TypesToLoadAttributeFullName) + .SelectMany(i => GetTypesToLoad(i)); + + return typesToLoad; + } + + private static IEnumerable GetTypesToLoad(Attribute attribute) + { + if (attribute == null) + return Enumerable.Empty(); + + var type = attribute.GetType(); + var typesProperty = type.GetProperty("Types"); + if(typesProperty == null) + return Enumerable.Empty(); + + return typesProperty.GetValue(attribute) as Type[]; + } + } +} diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/AssemblyInfo.cs index 68809aec87..33717a5453 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/AssemblyInfo.cs @@ -3,8 +3,6 @@ using System.Reflection; using System.Runtime.InteropServices; -using Microsoft.TestPlatform.Extensions.BlameDataCollector; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -14,7 +12,6 @@ [assembly: AssemblyCopyright(" Microsoft Corporation. All rights reserved.")] [assembly: AssemblyProduct("Microsoft.TestPlatform.Extensions.BlameDataCollector")] [assembly: AssemblyTrademark("")] -[assembly: TypesToLoad(typeof(BlameLogger), typeof(BlameCollector))] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/TypesToLoadAttribute.cs new file mode 100644 index 0000000000..850d091188 --- /dev/null +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/TypesToLoadAttribute.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. + +using System; + +using Microsoft.TestPlatform.Extensions.BlameDataCollector; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + +[assembly: TypesToLoad(typeof(BlameLogger), typeof(BlameCollector))] + +namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities +{ + /// + /// Custom Attribute to specify the exact types which should be loaded from assembly + /// + [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] + internal sealed class TypesToLoadAttribute : Attribute + { + public TypesToLoadAttribute(params Type[] types) + { + this.Types = types; + } + + public Type[] Types { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/AssemblyInfo.cs index bc64c4ba85..4010518fda 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/AssemblyInfo.cs @@ -3,8 +3,6 @@ using System.Reflection; using System.Runtime.InteropServices; -using Microsoft.VisualStudio.TestPlatform.Extensions.HtmlLogger; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -14,7 +12,6 @@ [assembly: AssemblyCopyright(" Microsoft Corporation. All rights reserved.")] [assembly: AssemblyProduct("Microsoft.TestPlatform.Extensions.HtmlLogger")] [assembly: AssemblyTrademark("")] -[assembly: TypesToLoad(typeof(HtmlLogger))] // Setting ComVisible to false makes the types in this assembly not visible @@ -23,5 +20,4 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM. - [assembly: Guid("1f26e9c7-5018-4091-a22a-89280f2f98a9")] diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/TypesToLoadAttribute.cs new file mode 100644 index 0000000000..a80f7cc16d --- /dev/null +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/TypesToLoadAttribute.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. + +using System; +using Microsoft.VisualStudio.TestPlatform.Extensions.HtmlLogger; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + +[assembly: TypesToLoad(typeof(HtmlLogger))] + +namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities +{ + /// + /// Custom Attribute to specify the exact types which should be loaded from assembly + /// + [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] + internal sealed class TypesToLoadAttribute : Attribute + { + public TypesToLoadAttribute(params Type[] types) + { + this.Types = types; + } + + public Type[] Types { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/AssemblyInfo.cs index 57f3f4ab80..816dbd6b88 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/AssemblyInfo.cs @@ -14,7 +14,6 @@ [assembly: AssemblyCopyright(" Microsoft Corporation. All rights reserved.")] [assembly: AssemblyProduct("Microsoft.TestPlatform.Extensions.TrxLogger")] [assembly: AssemblyTrademark("")] -[assembly: TypesToLoad(typeof(TrxLogger))] // Setting ComVisible to false makes the types in this assembly not visible @@ -23,4 +22,4 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("60d876ee-f278-4bf8-bc8a-15b356895c6f")] +[assembly: Guid("60d876ee-f278-4bf8-bc8a-15b356895c6f")] \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/TypesToLoadAttribute.cs new file mode 100644 index 0000000000..e92219c4a8 --- /dev/null +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/TypesToLoadAttribute.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. + +using System; +using Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + +[assembly: TypesToLoad(typeof(TrxLogger))] + +namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities +{ + /// + /// Custom Attribute to specify the exact types which should be loaded from assembly + /// + [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] + internal sealed class TypesToLoadAttribute : Attribute + { + public TypesToLoadAttribute(params Type[] types) + { + this.Types = types; + } + + public Type[] Types { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Utilities/AssemblyHelper.cs b/src/Microsoft.TestPlatform.ObjectModel/Utilities/AssemblyHelper.cs index 3c1616c217..48994399c1 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Utilities/AssemblyHelper.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Utilities/AssemblyHelper.cs @@ -3,20 +3,21 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities { -#if NETFRAMEWORK + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; + using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; + using System.Linq; using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; - /// /// Implementation of finding assembly references using "managed route", i.e. Assembly.Load. /// public static class AssemblyHelper { +#if NETFRAMEWORK private static Version defaultVersion = new Version(); private static Version version45 = new Version("4.5"); @@ -25,7 +26,6 @@ public static class AssemblyHelper /// Only assembly name and public key token are match. Version is ignored for matching. /// Returns null if not able to check if source references assembly. /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] public static bool? DoesReferencesAssembly(string source, AssemblyName referenceAssembly) { try @@ -160,7 +160,6 @@ public static KeyValuePair GetFrameworkVersionAn } } - /// /// Returns the full name (AssemblyName.FullName) of the referenced assemblies by the assembly on the specified path. /// @@ -340,6 +339,18 @@ internal static void SetNETFrameworkCompatiblityMode(AppDomainSetup setup, IRunC } } } - } #endif + + public static IEnumerable GetCustomAttributes(this Assembly assembly, string fullyQualifiedName) + { + ValidateArg.NotNull(assembly, nameof(assembly)); + ValidateArg.NotNullOrWhiteSpace(fullyQualifiedName, nameof(fullyQualifiedName)); + + var attributes = assembly + .GetCustomAttributes() + .Where(i => i.GetType().FullName == fullyQualifiedName); + + return attributes; + } + } } diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.TestHostProvider/Properties/AssemblyInfo.cs index cfcaf11468..892e0ae7e4 100644 --- a/src/Microsoft.TestPlatform.TestHostProvider/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.TestHostProvider/Properties/AssemblyInfo.cs @@ -3,8 +3,6 @@ using System.Reflection; using System.Runtime.InteropServices; -using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -14,7 +12,6 @@ [assembly: AssemblyCopyright(" Microsoft Corporation. All rights reserved.")] [assembly: AssemblyProduct("Microsoft.TestPlatform.TestHostRuntimeProvider")] [assembly: AssemblyTrademark("")] -[assembly: TypesToLoad(typeof(DefaultTestHostManager), typeof(DotnetTestHostManager))] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.TestHostProvider/Properties/TypesToLoadAttribute.cs new file mode 100644 index 0000000000..33805104af --- /dev/null +++ b/src/Microsoft.TestPlatform.TestHostProvider/Properties/TypesToLoadAttribute.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. + +using System; +using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; + +[assembly: TypesToLoad(typeof(DefaultTestHostManager), typeof(DotnetTestHostManager))] + +namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities +{ + /// + /// Custom Attribute to specify the exact types which should be loaded from assembly + /// + [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] + internal sealed class TypesToLoadAttribute : Attribute + { + public TypesToLoadAttribute(params Type[] types) + { + this.Types = types; + } + + public Type[] Types { get; } + } +} \ No newline at end of file diff --git a/src/testhost.x86/testhost.x86.csproj b/src/testhost.x86/testhost.x86.csproj index 1527b52d70..b0a9d8eea3 100644 --- a/src/testhost.x86/testhost.x86.csproj +++ b/src/testhost.x86/testhost.x86.csproj @@ -3,6 +3,7 @@ ..\..\ false + true diff --git a/src/testhost/testhost.csproj b/src/testhost/testhost.csproj index a55ef48bb7..f8991d48a3 100644 --- a/src/testhost/testhost.csproj +++ b/src/testhost/testhost.csproj @@ -3,6 +3,7 @@ ..\..\ false + true diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/DiscoveryTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/DiscoveryTests.cs index d671d4d94c..155772fbd5 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/DiscoveryTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/DiscoveryTests.cs @@ -4,7 +4,13 @@ namespace Microsoft.TestPlatform.AcceptanceTests { using System; + using System.Collections.Generic; using System.IO; + using System.Linq; + using System.Reflection; + + using Microsoft.TestPlatform.TestUtilities; + using Microsoft.VisualStudio.TestPlatform.Common.Utilities; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -91,5 +97,31 @@ public void DiscoverTestsShouldShowProperWarningIfNoTestsOnTestCaseFilter(Runner this.ExitCodeEquals(0); } + + [TestMethod] + public void TypesToLoadAttributeTests() + { + var environment = new IntegrationTestEnvironment(); + var extensionsDirectory = environment.ExtensionsDirectory; + var extensionsToVerify = new Dictionary + { + {"Microsoft.TestPlatform.Extensions.EventLogCollector.dll", new[] { "Microsoft.TestPlatform.Extensions.EventLogCollector.EventLogDataCollector"} }, + {"Microsoft.TestPlatform.Extensions.BlameDataCollector.dll", new[] { "Microsoft.TestPlatform.Extensions.BlameDataCollector.BlameLogger", "Microsoft.TestPlatform.Extensions.BlameDataCollector.BlameCollector" } }, + {"Microsoft.VisualStudio.TestPlatform.Extensions.Html.TestLogger.dll", new[] { "Microsoft.VisualStudio.TestPlatform.Extensions.HtmlLogger.HtmlLogger" } }, + {"Microsoft.VisualStudio.TestPlatform.Extensions.Trx.TestLogger.dll", new[] { "Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.TrxLogger" } }, + {"Microsoft.TestPlatform.TestHostRuntimeProvider.dll", new[] { "Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting.DefaultTestHostManager", "Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting.DotnetTestHostManager" } } + }; + + foreach (var extension in extensionsToVerify.Keys) + { + var assemblyFile = Path.Combine(extensionsDirectory, extension); + var assembly = Assembly.LoadFrom(assemblyFile); + + var expected = extensionsToVerify[extension]; + var actual = TypesToLoadUtilities.GetTypesToLoad(assembly).Select(i => i.FullName).ToArray(); + + CollectionAssert.AreEquivalent(expected, actual, $"Specified types using TypesToLoadAttribute in \"{extension}\" assembly doesn't match the expected."); + } + } } } diff --git a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs index cff43c4ca2..947ad4b53d 100644 --- a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs +++ b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs @@ -97,7 +97,6 @@ public string PublishDirectory { get { - // this used to switch to src\package\package\bin\based on whether // this is running in cli, but that's a bad idea, the console there does not have // a runtime config and will fail to start with error testhostpolicy.dll not found @@ -117,6 +116,11 @@ public string PublishDirectory } } + /// + /// Gets the extensions directory for vstest.console package. + /// + public string ExtensionsDirectory => Path.Combine(PublishDirectory, "Extensions"); + /// /// Gets the target framework. /// Supported values = net451, netcoreapp1.0. From 5fe257c6d7fb4285824c234a62d9982ee096ecd9 Mon Sep 17 00:00:00 2001 From: Medeni Baykal <433724+Haplois@users.noreply.github.com> Date: Tue, 15 Dec 2020 12:52:40 +0100 Subject: [PATCH 09/46] Attribute refactoring (#2676) --- ...atform.Extensions.EventLogCollector.csproj | 7 +++-- .../Properties/AssemblyInfo.cs | 5 +++- .../Properties/TypesToLoadAttribute.cs | 25 ------------------ ...oft.VisualStudio.TraceDataCollector.csproj | 7 +++-- .../Properties/AssemblyInfo.cs | 5 ++++ .../Utilities/TypesToLoadUtilities.cs | 2 +- ...tform.Extensions.BlameDataCollector.csproj | 7 +++-- .../Properties/AssemblyInfo.cs | 5 ++++ .../Properties/TypesToLoadAttribute.cs | 26 ------------------- ....TestPlatform.Extensions.HtmlLogger.csproj | 7 +++-- .../Properties/AssemblyInfo.cs | 5 ++++ .../Properties/TypesToLoadAttribute.cs | 25 ------------------ ...t.TestPlatform.Extensions.TrxLogger.csproj | 7 +++-- .../Properties/AssemblyInfo.cs | 7 +++-- .../Properties/TypesToLoadAttribute.cs | 25 ------------------ .../Utilities/AssemblyHelper.cs | 9 ++++--- .../Properties/AssemblyInfo.cs | 5 ++++ .../TestExtensionTypesAttribute.cs} | 14 ++++------ .../Properties/TypesToLoadAttribute.cs | 25 ------------------ 19 files changed, 66 insertions(+), 152 deletions(-) delete mode 100644 src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/TypesToLoadAttribute.cs delete mode 100644 src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/TypesToLoadAttribute.cs delete mode 100644 src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/TypesToLoadAttribute.cs delete mode 100644 src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/TypesToLoadAttribute.cs rename src/{DataCollectors/TraceDataCollector/Properties/TypesToLoadAttribute.cs => Microsoft.TestPlatform.TestHostProvider/Properties/TestExtensionTypesAttribute.cs} (57%) delete mode 100644 src/Microsoft.TestPlatform.TestHostProvider/Properties/TypesToLoadAttribute.cs diff --git a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Microsoft.TestPlatform.Extensions.EventLogCollector.csproj b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Microsoft.TestPlatform.Extensions.EventLogCollector.csproj index 61c74ab8c2..80f85fe4e1 100644 --- a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Microsoft.TestPlatform.Extensions.EventLogCollector.csproj +++ b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Microsoft.TestPlatform.Extensions.EventLogCollector.csproj @@ -11,8 +11,11 @@ true - - + + + + + diff --git a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/AssemblyInfo.cs b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/AssemblyInfo.cs index e0e2c84b82..8f118204fd 100644 --- a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/AssemblyInfo.cs +++ b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/AssemblyInfo.cs @@ -3,8 +3,9 @@ using System.Reflection; using System.Runtime.InteropServices; + using Microsoft.TestPlatform.Extensions.EventLogCollector; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; +using Microsoft.VisualStudio.TestPlatform; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -22,3 +23,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("4c1f0d81-67a9-4bf3-a006-615ab4a7fcd6")] + +[assembly: TestExtensionTypes(typeof(EventLogDataCollector))] \ No newline at end of file diff --git a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/TypesToLoadAttribute.cs b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/TypesToLoadAttribute.cs deleted file mode 100644 index 0869251ec9..0000000000 --- a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/Properties/TypesToLoadAttribute.cs +++ /dev/null @@ -1,25 +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; -using Microsoft.TestPlatform.Extensions.EventLogCollector; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; - -[assembly: TypesToLoad(typeof(EventLogDataCollector))] - -namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities -{ - /// - /// Custom Attribute to specify the exact types which should be loaded from assembly - /// - [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] - internal sealed class TypesToLoadAttribute : Attribute - { - public TypesToLoadAttribute(params Type[] types) - { - this.Types = types; - } - - public Type[] Types { get; } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Microsoft.VisualStudio.TraceDataCollector.csproj b/src/DataCollectors/TraceDataCollector/Microsoft.VisualStudio.TraceDataCollector.csproj index 4526e2b69c..ddc4444ce0 100644 --- a/src/DataCollectors/TraceDataCollector/Microsoft.VisualStudio.TraceDataCollector.csproj +++ b/src/DataCollectors/TraceDataCollector/Microsoft.VisualStudio.TraceDataCollector.csproj @@ -14,8 +14,11 @@ - - + + + + + diff --git a/src/DataCollectors/TraceDataCollector/Properties/AssemblyInfo.cs b/src/DataCollectors/TraceDataCollector/Properties/AssemblyInfo.cs index e7212dbc3d..348b5dcdfc 100644 --- a/src/DataCollectors/TraceDataCollector/Properties/AssemblyInfo.cs +++ b/src/DataCollectors/TraceDataCollector/Properties/AssemblyInfo.cs @@ -4,6 +4,9 @@ using System.Reflection; using System.Runtime.InteropServices; +using Microsoft.VisualStudio.Coverage; +using Microsoft.VisualStudio.TestPlatform; + // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. @@ -20,3 +23,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("b06e12a5-025f-42aa-8f09-c6666c65ece7")] + +[assembly: TestExtensionTypes(typeof(DynamicCoverageDataCollector))] \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Utilities/TypesToLoadUtilities.cs b/src/Microsoft.TestPlatform.Common/Utilities/TypesToLoadUtilities.cs index fb25c588ff..22f568f399 100644 --- a/src/Microsoft.TestPlatform.Common/Utilities/TypesToLoadUtilities.cs +++ b/src/Microsoft.TestPlatform.Common/Utilities/TypesToLoadUtilities.cs @@ -13,7 +13,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.Utilities internal static class TypesToLoadUtilities { - public const string TypesToLoadAttributeFullName = "Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities.TypesToLoadAttribute"; + public const string TypesToLoadAttributeFullName = "Microsoft.VisualStudio.TestPlatform.TestExtensionTypesAttribute"; internal static IEnumerable GetTypesToLoad(Assembly assembly) { 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 11a26e7f56..e88e26ab36 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj @@ -16,12 +16,15 @@ true + + + - - + + diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/AssemblyInfo.cs index 33717a5453..dc8cee6a54 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/AssemblyInfo.cs @@ -4,6 +4,9 @@ using System.Reflection; using System.Runtime.InteropServices; +using Microsoft.TestPlatform.Extensions.BlameDataCollector; +using Microsoft.VisualStudio.TestPlatform; + // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. @@ -20,3 +23,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("716373d6-9162-4ac6-9ae7-b5a3a4286808")] + +[assembly: TestExtensionTypes(typeof(BlameLogger), typeof(BlameCollector))] \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/TypesToLoadAttribute.cs deleted file mode 100644 index 850d091188..0000000000 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Properties/TypesToLoadAttribute.cs +++ /dev/null @@ -1,26 +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; - -using Microsoft.TestPlatform.Extensions.BlameDataCollector; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; - -[assembly: TypesToLoad(typeof(BlameLogger), typeof(BlameCollector))] - -namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities -{ - /// - /// Custom Attribute to specify the exact types which should be loaded from assembly - /// - [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] - internal sealed class TypesToLoadAttribute : Attribute - { - public TypesToLoadAttribute(params Type[] types) - { - this.Types = types; - } - - public Type[] Types { get; } - } -} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Microsoft.TestPlatform.Extensions.HtmlLogger.csproj b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Microsoft.TestPlatform.Extensions.HtmlLogger.csproj index 9025a0d8c1..e4c3045ff6 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Microsoft.TestPlatform.Extensions.HtmlLogger.csproj +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Microsoft.TestPlatform.Extensions.HtmlLogger.csproj @@ -21,8 +21,11 @@ - - + + + + + diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/AssemblyInfo.cs index 4010518fda..8ea41b1b09 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/AssemblyInfo.cs @@ -4,6 +4,9 @@ using System.Reflection; using System.Runtime.InteropServices; +using Microsoft.VisualStudio.TestPlatform; +using Microsoft.VisualStudio.TestPlatform.Extensions.HtmlLogger; + // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. @@ -21,3 +24,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM. [assembly: Guid("1f26e9c7-5018-4091-a22a-89280f2f98a9")] + +[assembly: TestExtensionTypes(typeof(HtmlLogger))] \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/TypesToLoadAttribute.cs deleted file mode 100644 index a80f7cc16d..0000000000 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Properties/TypesToLoadAttribute.cs +++ /dev/null @@ -1,25 +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; -using Microsoft.VisualStudio.TestPlatform.Extensions.HtmlLogger; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; - -[assembly: TypesToLoad(typeof(HtmlLogger))] - -namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities -{ - /// - /// Custom Attribute to specify the exact types which should be loaded from assembly - /// - [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] - internal sealed class TypesToLoadAttribute : Attribute - { - public TypesToLoadAttribute(params Type[] types) - { - this.Types = types; - } - - public Type[] Types { get; } - } -} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Microsoft.TestPlatform.Extensions.TrxLogger.csproj b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Microsoft.TestPlatform.Extensions.TrxLogger.csproj index 2450ff93ab..f8fa6e6985 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Microsoft.TestPlatform.Extensions.TrxLogger.csproj +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Microsoft.TestPlatform.Extensions.TrxLogger.csproj @@ -20,8 +20,11 @@ - - + + + + + diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/AssemblyInfo.cs index 816dbd6b88..51c82b3d1a 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/AssemblyInfo.cs @@ -3,8 +3,9 @@ using System.Reflection; using System.Runtime.InteropServices; + +using Microsoft.VisualStudio.TestPlatform; using Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -22,4 +23,6 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("60d876ee-f278-4bf8-bc8a-15b356895c6f")] \ No newline at end of file +[assembly: Guid("60d876ee-f278-4bf8-bc8a-15b356895c6f")] + +[assembly: TestExtensionTypes(typeof(TrxLogger))] \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/TypesToLoadAttribute.cs deleted file mode 100644 index e92219c4a8..0000000000 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Properties/TypesToLoadAttribute.cs +++ /dev/null @@ -1,25 +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; -using Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; - -[assembly: TypesToLoad(typeof(TrxLogger))] - -namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities -{ - /// - /// Custom Attribute to specify the exact types which should be loaded from assembly - /// - [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] - internal sealed class TypesToLoadAttribute : Attribute - { - public TypesToLoadAttribute(params Type[] types) - { - this.Types = types; - } - - public Type[] Types { get; } - } -} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Utilities/AssemblyHelper.cs b/src/Microsoft.TestPlatform.ObjectModel/Utilities/AssemblyHelper.cs index 48994399c1..880e830449 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Utilities/AssemblyHelper.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Utilities/AssemblyHelper.cs @@ -346,11 +346,14 @@ public static IEnumerable GetCustomAttributes(this Assembly assembly, ValidateArg.NotNull(assembly, nameof(assembly)); ValidateArg.NotNullOrWhiteSpace(fullyQualifiedName, nameof(fullyQualifiedName)); - var attributes = assembly + if(assembly.GetType(fullyQualifiedName) is Type attribute) + { + return assembly.GetCustomAttributes(attribute); + } + + return assembly .GetCustomAttributes() .Where(i => i.GetType().FullName == fullyQualifiedName); - - return attributes; } } } diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.TestHostProvider/Properties/AssemblyInfo.cs index 892e0ae7e4..d92238b7ba 100644 --- a/src/Microsoft.TestPlatform.TestHostProvider/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.TestHostProvider/Properties/AssemblyInfo.cs @@ -4,6 +4,9 @@ using System.Reflection; using System.Runtime.InteropServices; +using Microsoft.VisualStudio.TestPlatform; +using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting; + // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. @@ -20,3 +23,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("83693884-04ee-4083-bae1-e7827b8f5fbc")] + +[assembly: TestExtensionTypes(typeof(DefaultTestHostManager), typeof(DotnetTestHostManager))] \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.TestHostProvider/Properties/TestExtensionTypesAttribute.cs similarity index 57% rename from src/DataCollectors/TraceDataCollector/Properties/TypesToLoadAttribute.cs rename to src/Microsoft.TestPlatform.TestHostProvider/Properties/TestExtensionTypesAttribute.cs index 48cad540f0..4cce7e2fbc 100644 --- a/src/DataCollectors/TraceDataCollector/Properties/TypesToLoadAttribute.cs +++ b/src/Microsoft.TestPlatform.TestHostProvider/Properties/TestExtensionTypesAttribute.cs @@ -1,21 +1,17 @@ // 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; -using Microsoft.VisualStudio.Coverage; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; - -[assembly: TypesToLoad(typeof(DynamicCoverageDataCollector))] - -namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities +namespace Microsoft.VisualStudio.TestPlatform { + using System; + /// /// Custom Attribute to specify the exact types which should be loaded from assembly /// [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] - internal sealed class TypesToLoadAttribute : Attribute + internal sealed class TestExtensionTypesAttribute : Attribute { - public TypesToLoadAttribute(params Type[] types) + public TestExtensionTypesAttribute(params Type[] types) { this.Types = types; } diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Properties/TypesToLoadAttribute.cs b/src/Microsoft.TestPlatform.TestHostProvider/Properties/TypesToLoadAttribute.cs deleted file mode 100644 index 33805104af..0000000000 --- a/src/Microsoft.TestPlatform.TestHostProvider/Properties/TypesToLoadAttribute.cs +++ /dev/null @@ -1,25 +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; -using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; - -[assembly: TypesToLoad(typeof(DefaultTestHostManager), typeof(DotnetTestHostManager))] - -namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities -{ - /// - /// Custom Attribute to specify the exact types which should be loaded from assembly - /// - [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] - internal sealed class TypesToLoadAttribute : Attribute - { - public TypesToLoadAttribute(params Type[] types) - { - this.Types = types; - } - - public Type[] Types { get; } - } -} \ No newline at end of file From faa2783a7d5ce625eb2a63e2d1fa7d8c4101612f Mon Sep 17 00:00:00 2001 From: fhnaseer Date: Wed, 16 Dec 2020 15:50:54 +0100 Subject: [PATCH 10/46] Getting TraceDataCollector from nuget (#2678) * Removing TraceDataCollector project, * Getting tracedatacollector from nuget, * Removing signing of codecoverage libs as they are already signed, updating codecoverage version, * fixing path to tracedatacollector, * Fixing acceptance tests, Co-authored-by: faisal --- TestPlatform.sln | 30 - scripts/build.ps1 | 39 +- scripts/build/TestPlatform.Dependencies.props | 2 +- scripts/test.ps1 | 2 +- scripts/verify-nupkgs.ps1 | 4 +- .../TraceDataCollector/BaseDataCollector.cs | 76 -- ...DataCollectionEnvironmentContextWrapper.cs | 23 - .../DataCollectionEventsWrapper.cs | 47 - .../DataCollectionLoggerWrapper.cs | 43 - .../DataCollectionSinkWrapper.cs | 48 - .../Interfaces/IDataCollectionAgentContext.cs | 16 - .../Interfaces/IDataCollectionEvents.cs | 23 - .../Interfaces/IDataCollectionLogger.cs | 23 - .../Interfaces/IDataCollectionSink.cs | 23 - .../TraceDataCollector/DirectoryHelper.cs | 30 - .../TraceDataCollector/FileHelper.cs | 24 - .../TraceDataCollector/Friends.cs | 8 - .../Interfaces/IDirectoryHelper.cs | 32 - .../Interfaces/IEnvironment.cs | 16 - .../Interfaces/IFileHelper.cs | 29 - .../Interfaces/IProcessJobObject.cs | 22 - .../Interfaces/PlatformOperationSystem.cs | 14 - ...oft.VisualStudio.TraceDataCollector.csproj | 51 - .../TraceDataCollector/PlatformEnvironment.cs | 26 - .../TraceDataCollector/ProcessJobObject.cs | 875 ------------------ .../Properties/AssemblyInfo.cs | 27 - .../Resources/Resources.Designer.cs | 118 --- .../Resources/Resources.resx | 138 --- .../Resources/xlf/Resources.cs.xlf | 55 -- .../Resources/xlf/Resources.de.xlf | 55 -- .../Resources/xlf/Resources.es.xlf | 55 -- .../Resources/xlf/Resources.fr.xlf | 55 -- .../Resources/xlf/Resources.it.xlf | 55 -- .../Resources/xlf/Resources.ja.xlf | 55 -- .../Resources/xlf/Resources.ko.xlf | 55 -- .../Resources/xlf/Resources.pl.xlf | 55 -- .../Resources/xlf/Resources.pt-BR.xlf | 55 -- .../Resources/xlf/Resources.ru.xlf | 55 -- .../Resources/xlf/Resources.tr.xlf | 55 -- .../Resources/xlf/Resources.xlf | 37 - .../Resources/xlf/Resources.zh-Hans.xlf | 55 -- .../Resources/xlf/Resources.zh-Hant.xlf | 55 -- .../DefaultCodeCoverageConfig.xml | 77 -- .../DynamicCoverageDataCollector.cs | 259 ------ .../DynamicCoverageDataCollectorImpl.cs | 392 -------- .../IDynamicCoverageDataCollectorImpl.cs | 30 - .../Interfaces/IProfilersLocationProvider.cs | 59 -- .../VanguardCollector/Interfaces/IVanguard.cs | 38 - .../Interfaces/IVanguardCommandBuilder.cs | 25 - .../Interfaces/VanguardCommand.cs | 21 - .../ProfilersLocationProvider.cs | 108 --- .../VanguardCollector/Vanguard.cs | 373 -------- .../VanguardCommandBuilder.cs | 47 - .../VanguardCollector/VanguardException.cs | 23 - .../nuspec/Microsoft.CodeCoverage.nuspec | 28 +- .../nuspec/Microsoft.TestPlatform.nuspec | 15 +- src/package/sign/sign.proj | 14 - .../DefaultCodeCoverageConfig.xml | 74 -- .../DynamicCoverageDataCollectorImplTests.cs | 489 ---------- .../DynamicCoverageDataCollectorTests.cs | 412 --------- ...atform.TraceDataCollector.UnitTests.csproj | 30 - .../ProfilersLocationProviderTests.cs | 119 --- .../TraceDataCollector.UnitTests/Program.cs | 14 - .../Properties/AssemblyInfo.cs | 21 - .../VanguardCommandBuilderTests.cs | 50 - .../VanguardTests.cs | 204 ---- .../CodeCoverageTests.cs | 2 +- 67 files changed, 50 insertions(+), 5435 deletions(-) delete mode 100644 src/DataCollectors/TraceDataCollector/BaseDataCollector.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionEnvironmentContextWrapper.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionEventsWrapper.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionLoggerWrapper.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionSinkWrapper.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionAgentContext.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionEvents.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionLogger.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionSink.cs delete mode 100644 src/DataCollectors/TraceDataCollector/DirectoryHelper.cs delete mode 100644 src/DataCollectors/TraceDataCollector/FileHelper.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Friends.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Interfaces/IDirectoryHelper.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Interfaces/IEnvironment.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Interfaces/IFileHelper.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Interfaces/IProcessJobObject.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Interfaces/PlatformOperationSystem.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Microsoft.VisualStudio.TraceDataCollector.csproj delete mode 100644 src/DataCollectors/TraceDataCollector/PlatformEnvironment.cs delete mode 100644 src/DataCollectors/TraceDataCollector/ProcessJobObject.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Properties/AssemblyInfo.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/Resources.Designer.cs delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/Resources.resx delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.cs.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.de.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.es.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.fr.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.it.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ja.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ko.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.pl.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.pt-BR.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ru.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.tr.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.zh-Hans.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.zh-Hant.xlf delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/DefaultCodeCoverageConfig.xml delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/DynamicCoverageDataCollector.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/DynamicCoverageDataCollectorImpl.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IDynamicCoverageDataCollectorImpl.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IProfilersLocationProvider.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IVanguard.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IVanguardCommandBuilder.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/VanguardCommand.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/ProfilersLocationProvider.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/Vanguard.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/VanguardCommandBuilder.cs delete mode 100644 src/DataCollectors/TraceDataCollector/VanguardCollector/VanguardException.cs delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/DefaultCodeCoverageConfig.xml delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/DynamicCoverageDataCollectorImplTests.cs delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/DynamicCoverageDataCollectorTests.cs delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/Microsoft.TestPlatform.TraceDataCollector.UnitTests.csproj delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/ProfilersLocationProviderTests.cs delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/Program.cs delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/Properties/AssemblyInfo.cs delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/VanguardCommandBuilderTests.cs delete mode 100644 test/DataCollectors/TraceDataCollector.UnitTests/VanguardTests.cs diff --git a/TestPlatform.sln b/TestPlatform.sln index 4150d781ae..9d14b72dc8 100644 --- a/TestPlatform.sln +++ b/TestPlatform.sln @@ -142,10 +142,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vstest.console.PlatformTest EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Common.PlatformTests", "test\Microsoft.TestPlatform.Common.PlatformTests\Microsoft.TestPlatform.Common.PlatformTests.csproj", "{24C7683D-2607-4901-B8EB-83A57E49E93D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.TraceDataCollector", "src\DataCollectors\TraceDataCollector\Microsoft.VisualStudio.TraceDataCollector.csproj", "{32BD96BD-16FB-43F0-B952-E7EEDB6DD813}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.TraceDataCollector.UnitTests", "test\DataCollectors\TraceDataCollector.UnitTests\Microsoft.TestPlatform.TraceDataCollector.UnitTests.csproj", "{A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SettingsMigrator", "src\SettingsMigrator\SettingsMigrator.csproj", "{69F5FF81-5615-4F06-B83C-FCF979BB84CA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SettingsMigrator.UnitTests", "test\SettingsMigrator.UnitTests\SettingsMigrator.UnitTests.csproj", "{E7D4921C-F12D-4E1C-85AC-8B7F91C59B0E}" @@ -696,30 +692,6 @@ Global {24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|x64.Build.0 = Release|Any CPU {24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|x86.ActiveCfg = Release|Any CPU {24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|x86.Build.0 = Release|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Debug|Any CPU.Build.0 = Debug|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Debug|x64.ActiveCfg = Debug|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Debug|x64.Build.0 = Debug|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Debug|x86.ActiveCfg = Debug|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Debug|x86.Build.0 = Debug|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Release|Any CPU.ActiveCfg = Release|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Release|Any CPU.Build.0 = Release|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Release|x64.ActiveCfg = Release|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Release|x64.Build.0 = Release|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Release|x86.ActiveCfg = Release|Any CPU - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813}.Release|x86.Build.0 = Release|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Debug|x64.ActiveCfg = Debug|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Debug|x64.Build.0 = Debug|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Debug|x86.ActiveCfg = Debug|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Debug|x86.Build.0 = Debug|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Release|Any CPU.Build.0 = Release|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Release|x64.ActiveCfg = Release|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Release|x64.Build.0 = Release|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Release|x86.ActiveCfg = Release|Any CPU - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3}.Release|x86.Build.0 = Release|Any CPU {69F5FF81-5615-4F06-B83C-FCF979BB84CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {69F5FF81-5615-4F06-B83C-FCF979BB84CA}.Debug|Any CPU.Build.0 = Debug|Any CPU {69F5FF81-5615-4F06-B83C-FCF979BB84CA}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -853,8 +825,6 @@ Global {0D4DF78D-7E5F-4516-B19F-E6AA71A1DBF4} = {EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330} {8C068694-23A2-47A2-A0DD-DB82D0AF0142} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} {24C7683D-2607-4901-B8EB-83A57E49E93D} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} - {32BD96BD-16FB-43F0-B952-E7EEDB6DD813} = {B705537C-B82C-4A30-AFA5-6244D9A7DAEB} - {A7E2261B-B2E6-4CBF-983F-E3A3FF8E52E3} = {D9A30E32-D466-4EC5-B4F2-62E17562279B} {69F5FF81-5615-4F06-B83C-FCF979BB84CA} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} {E7D4921C-F12D-4E1C-85AC-8B7F91C59B0E} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {236A71E3-01DA-4679-9DFF-16A8E079ACFF} = {5E7F18A8-F843-4C8A-AB02-4C7D9205C6CF} diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 7e26bb4637..fb08b7064c 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -568,17 +568,6 @@ function Publish-Package } Copy-Item -Recurse $intellitraceSourceDirectory\* $intellitraceTargetDirectory -Force - - # Copy Microsoft.VisualStudio.TraceDataCollector - $codeCoverageExternalsVersion = ([xml](Get-Content $env:TP_ROOT_DIR\scripts\build\TestPlatform.Dependencies.props)).Project.PropertyGroup.CodeCoverageExternalsVersion - $traceDataCollectorSourceDirectory = Join-Path $env:TP_PACKAGES_DIR "Microsoft.VisualStudio.TraceDataCollector\$codeCoverageExternalsVersion\lib" - $traceDataCollectorTargetDirectory = Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.VisualStudio.TraceDataCollector" - - if (-not (Test-Path $traceDataCollectorTargetDirectory)) { - New-Item $traceDataCollectorTargetDirectory -Type Directory -Force | Out-Null - } - - Copy-Item -Recurse $traceDataCollectorSourceDirectory\* $traceDataCollectorTargetDirectory -Force # Copy Microsoft.VisualStudio.Telemetry APIs $testPlatformDirectory = Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Intellitrace\Common7\IDE\Extensions\TestPlatform" @@ -699,8 +688,11 @@ function Create-VsixPackage $codeCoverageExternalsVersion = ([xml](Get-Content $env:TP_ROOT_DIR\scripts\build\TestPlatform.Dependencies.props)).Project.PropertyGroup.CodeCoverageExternalsVersion # Copy Microsoft.VisualStudio.TraceDataCollector to Extensions - $traceDataCollectorSourceDirectory = Join-Path $env:TP_PACKAGES_DIR "Microsoft.VisualStudio.TraceDataCollector\$codeCoverageExternalsVersion\lib\net472" - Copy-Item $traceDataCollectorSourceDirectory\Microsoft.VisualStudio.TraceDataCollector.dll $extensionsPackageDir -Force + $traceDataCollectorPackageDirectory = Join-Path $env:TP_PACKAGES_DIR "Microsoft.VisualStudio.TraceDataCollector\$codeCoverageExternalsVersion\lib\$TPB_TargetFramework472" + Copy-Item $traceDataCollectorPackageDirectory\Microsoft.VisualStudio.TraceDataCollector.dll $extensionsPackageDir -Force + if($TPB_LocalizedBuild) { + Copy-Loc-Files $traceDataCollectorPackageDirectory $extensionsPackageDir "Microsoft.VisualStudio.TraceDataCollector.resources.dll" + } # Copy legacy dependencies $legacyDir = Join-Path $env:TP_PACKAGES_DIR "Microsoft.Internal.TestPlatform.Extensions\$testPlatformExternalsVersion\contentFiles\any\any" @@ -825,6 +817,8 @@ function Create-NugetPackages # Additional external dependency folders $microsoftFakesVersion = ([xml](Get-Content $env:TP_ROOT_DIR\scripts\build\TestPlatform.Dependencies.props)).Project.PropertyGroup.MicrosoftFakesVersion $FakesPackageDir = Join-Path $env:TP_PACKAGES_DIR "Microsoft.QualityTools.Testing.Fakes.TestRunnerHarness\$microsoftFakesVersion\contentFiles" + $codeCoverageExternalsVersion = ([xml](Get-Content $env:TP_ROOT_DIR\scripts\build\TestPlatform.Dependencies.props)).Project.PropertyGroup.CodeCoverageExternalsVersion + $TraceDataCollectorPackagesDir = Join-Path $env:TP_PACKAGES_DIR "microsoft.visualstudio.tracedatacollector\$codeCoverageExternalsVersion\lib" # package them from stagingDir foreach ($file in $nuspecFiles) { @@ -834,7 +828,7 @@ function Create-NugetPackages } Write-Verbose "$nugetExe pack $stagingDir\$file -OutputDirectory $packageOutputDir -Version $TPB_Version -Properties Version=$TPB_Version $additionalArgs" - & $nugetExe pack $stagingDir\$file -OutputDirectory $packageOutputDir -Version $TPB_Version -Properties Version=$TPB_Version`;JsonNetVersion=$JsonNetVersion`;Runtime=$TPB_TargetRuntime`;NetCoreTargetFramework=$TPB_TargetFrameworkCore20`;FakesPackageDir=$FakesPackageDir`;NetStandard10Framework=$TPB_TargetFrameworkNS10`;NetStandard13Framework=$TPB_TargetFrameworkNS13`;NetStandard20Framework=$TPB_TargetFrameworkNS20`;Uap10Framework=$testhostUapPackageDir $additionalArgs + & $nugetExe pack $stagingDir\$file -OutputDirectory $packageOutputDir -Version $TPB_Version -Properties Version=$TPB_Version`;JsonNetVersion=$JsonNetVersion`;Runtime=$TPB_TargetRuntime`;NetCoreTargetFramework=$TPB_TargetFrameworkCore20`;FakesPackageDir=$FakesPackageDir`;TraceDataCollectorPackagesDir=$TraceDataCollectorPackagesDir`;NetStandard10Framework=$TPB_TargetFrameworkNS10`;NetStandard13Framework=$TPB_TargetFrameworkNS13`;NetStandard20Framework=$TPB_TargetFrameworkNS20`;Uap10Framework=$testhostUapPackageDir $additionalArgs Set-ScriptFailedOnError } @@ -849,21 +843,22 @@ function Create-NugetPackages function Copy-CodeCoverage-Package-Artifacts { # Copy TraceDataCollector to Microsoft.CodeCoverage folder. + $codeCoverageExternalsVersion = ([xml](Get-Content $env:TP_ROOT_DIR\scripts\build\TestPlatform.Dependencies.props)).Project.PropertyGroup.CodeCoverageExternalsVersion + $traceDataCollectorPackagesDir = Join-Path $env:TP_PACKAGES_DIR "microsoft.visualstudio.tracedatacollector\$codeCoverageExternalsVersion\lib\$TPB_TargetFrameworkNS20" + $internalCodeCoveragePackagesDir = Join-Path $env:TP_PACKAGES_DIR "microsoft.internal.codecoverage\$codeCoverageExternalsVersion\contentFiles\any\any\" + $microsoftCodeCoveragePackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.CodeCoverage\") New-Item -ItemType directory -Path $microsoftCodeCoveragePackageDir -Force | Out-Null - $traceDataCollectorOutDir = Join-Path $env:TP_ROOT_DIR "src\DataCollectors\TraceDataCollector\bin\$TPB_Configuration\$TPB_TargetFrameworkNS20" - - Copy-Item $traceDataCollectorOutDir\Microsoft.VisualStudio.TraceDataCollector.dll $microsoftCodeCoveragePackageDir -Force - Copy-Item $traceDataCollectorOutDir\Microsoft.VisualStudio.TraceDataCollector.pdb $microsoftCodeCoveragePackageDir -Force - Copy-Item $traceDataCollectorOutDir\CodeCoverage $microsoftCodeCoveragePackageDir -Force -Recurse - Copy-Item $traceDataCollectorOutDir\Shim $microsoftCodeCoveragePackageDir -Force -Recurse + Copy-Item $traceDataCollectorPackagesDir\Microsoft.VisualStudio.TraceDataCollector.dll $microsoftCodeCoveragePackageDir -Force + Copy-Item $traceDataCollectorPackagesDir\Microsoft.VisualStudio.TraceDataCollector.pdb $microsoftCodeCoveragePackageDir -Force + Copy-Item $internalCodeCoveragePackagesDir\CodeCoverage $microsoftCodeCoveragePackageDir -Force -Recurse + Copy-Item $internalCodeCoveragePackagesDir\Shim $microsoftCodeCoveragePackageDir -Force -Recurse # Copy TraceDataCollector resource dlls if($TPB_LocalizedBuild) { - Copy-Loc-Files $traceDataCollectorOutDir $microsoftCodeCoveragePackageDir "Microsoft.VisualStudio.TraceDataCollector.resources.dll" - Copy-Loc-Files $traceDataCollectorOutDir $microsoftCodeCoveragePackageDir "Microsoft.VisualStudio.TraceDataCollector.resources.dll" + Copy-Loc-Files $traceDataCollectorPackagesDir $microsoftCodeCoveragePackageDir "Microsoft.VisualStudio.TraceDataCollector.resources.dll" } } diff --git a/scripts/build/TestPlatform.Dependencies.props b/scripts/build/TestPlatform.Dependencies.props index 986afff988..9a09bf8876 100644 --- a/scripts/build/TestPlatform.Dependencies.props +++ b/scripts/build/TestPlatform.Dependencies.props @@ -32,7 +32,7 @@ 9.0.1 4.7.63 16.9.0-preview-4267359 - 16.9.0-beta.20603.1 + 16.9.0-beta.20616.2 16.9.0-beta.20602.2 16.0.461 diff --git a/scripts/test.ps1 b/scripts/test.ps1 index ed2bea934b..576849ddf3 100644 --- a/scripts/test.ps1 +++ b/scripts/test.ps1 @@ -111,7 +111,7 @@ $Script:TPT_TestResultsDir = Join-Path $env:TP_ROOT_DIR "TestResults" $Script:TPT_DefaultTrxFileName = "TrxLogResults.trx" $Script:TPT_ErrorMsgColor = "Red" $Script:TPT_RunSettingsFile = Join-Path (Get-Item (Split-Path $MyInvocation.MyCommand.Path)) "vstest-codecoverage.runsettings" -$Script:TPT_NSTraceDataCollectorPath = Join-Path $env:TP_ROOT_DIR "src\DataCollectors\TraceDataCollector\bin\$Script:TPT_Configuration\netstandard2.0" +$Script:TPT_NSTraceDataCollectorPath = Join-Path $env:TP_OUT_DIR "$Script:TPT_Configuration\Microsoft.CodeCoverage" # # Capture error state in any step globally to modify return code diff --git a/scripts/verify-nupkgs.ps1 b/scripts/verify-nupkgs.ps1 index 70f48ec763..6b2da27353 100644 --- a/scripts/verify-nupkgs.ps1 +++ b/scripts/verify-nupkgs.ps1 @@ -15,9 +15,9 @@ function Verify-Nuget-Packages($packageDirectory, $version) $expectedNumOfFiles = @{ "Microsoft.CodeCoverage" = 44; "Microsoft.NET.Test.Sdk" = 18; - "Microsoft.TestPlatform" = 486; + "Microsoft.TestPlatform" = 499; "Microsoft.TestPlatform.Build" = 19; - "Microsoft.TestPlatform.CLI" = 353; + "Microsoft.TestPlatform.CLI" = 379; "Microsoft.TestPlatform.Extensions.TrxLogger" = 33; "Microsoft.TestPlatform.ObjectModel" = 178; "Microsoft.TestPlatform.Portable" = 568; diff --git a/src/DataCollectors/TraceDataCollector/BaseDataCollector.cs b/src/DataCollectors/TraceDataCollector/BaseDataCollector.cs deleted file mode 100644 index e9c2b5081c..0000000000 --- a/src/DataCollectors/TraceDataCollector/BaseDataCollector.cs +++ /dev/null @@ -1,76 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System.Collections.Generic; - using System.Xml; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; - using TestPlatform.ObjectModel; - - /// - /// Implements the base event hooking logic for data collectors. - /// - /// - /// This class is used so that we can wrap the concrete objects given to us from the collector architecture with interfaces. - /// This allows us to mock up collectors for unit tests. - /// - public abstract class BaseDataCollector : DataCollector, ITestExecutionEnvironmentSpecifier - { - internal IDataCollectionEvents Events { get; private set; } - - internal IDataCollectionLogger Logger { get; private set; } - - internal IDataCollectionSink DataSink { get; private set; } - - internal IDataCollectionAgentContext AgentContext { get; private set; } - - #region Interface entry points - - public override void Initialize( - XmlElement configurationElement, - DataCollectionEvents events, - DataCollectionSink dataSink, - DataCollectionLogger logger, - DataCollectionEnvironmentContext environmentContext) - { - this.Initialize( - configurationElement, - new DataCollectionEventsWrapper(events), - new DataCollectionSinkWrapper(dataSink), - new DataCollectionLoggerWrapper(logger), - new DataCollectionEnvironmentContextWrapper(environmentContext)); - } - - IEnumerable> ITestExecutionEnvironmentSpecifier. - GetTestExecutionEnvironmentVariables() - { - return this.GetEnvironmentVariables(); - } - - #endregion - - internal void Initialize( - XmlElement configurationElement, - IDataCollectionEvents events, - IDataCollectionSink dataSink, - IDataCollectionLogger logger, - IDataCollectionAgentContext agentContext) - { - EqtTrace.Info( - "BaseDataCollector.InternalConstruct: Enabling datacollector with configuration: {0}", - configurationElement?.OuterXml); - this.Events = events; - this.DataSink = dataSink; - this.Logger = logger; - this.AgentContext = agentContext; - - this.OnInitialize(configurationElement); - } - - protected abstract void OnInitialize(XmlElement configurationElement); - - // Provide required environment variables for test execution through this method. - protected abstract IEnumerable> GetEnvironmentVariables(); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionEnvironmentContextWrapper.cs b/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionEnvironmentContextWrapper.cs deleted file mode 100644 index 8aaac18598..0000000000 --- a/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionEnvironmentContextWrapper.cs +++ /dev/null @@ -1,23 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using TestPlatform.ObjectModel.DataCollection; - - /// - internal sealed class DataCollectionEnvironmentContextWrapper : IDataCollectionAgentContext - { - private readonly DataCollectionEnvironmentContext environmentContext; - - public DataCollectionEnvironmentContextWrapper(DataCollectionEnvironmentContext environmentContext) - { - this.environmentContext = environmentContext; - } - - public DataCollectionContext SessionDataCollectionContext - { - get { return this.environmentContext.SessionDataCollectionContext; } - } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionEventsWrapper.cs b/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionEventsWrapper.cs deleted file mode 100644 index 4dffb285ee..0000000000 --- a/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionEventsWrapper.cs +++ /dev/null @@ -1,47 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System; - using TestPlatform.ObjectModel.DataCollection; - - /// - internal sealed class DataCollectionEventsWrapper : IDataCollectionEvents - { - private readonly DataCollectionEvents wrapped; - - public DataCollectionEventsWrapper(DataCollectionEvents wrapped) - { - this.wrapped = wrapped; - } - - #region IDataCollectionEvents Members - - event EventHandler IDataCollectionEvents.SessionEnd - { - add { this.wrapped.SessionEnd += value; } - remove { this.wrapped.SessionEnd -= value; } - } - - event EventHandler IDataCollectionEvents.SessionStart - { - add { this.wrapped.SessionStart += value; } - remove { this.wrapped.SessionStart -= value; } - } - - event EventHandler IDataCollectionEvents.TestCaseEnd - { - add { this.wrapped.TestCaseEnd += value; } - remove { this.wrapped.TestCaseEnd -= value; } - } - - event EventHandler IDataCollectionEvents.TestCaseStart - { - add { this.wrapped.TestCaseStart += value; } - remove { this.wrapped.TestCaseStart -= value; } - } - - #endregion - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionLoggerWrapper.cs b/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionLoggerWrapper.cs deleted file mode 100644 index 831fdfdd69..0000000000 --- a/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionLoggerWrapper.cs +++ /dev/null @@ -1,43 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System; - using TestPlatform.ObjectModel.DataCollection; - - /// - internal sealed class DataCollectionLoggerWrapper : IDataCollectionLogger - { - private readonly DataCollectionLogger wrapped; - - public DataCollectionLoggerWrapper(DataCollectionLogger wrapped) - { - this.wrapped = wrapped; - } - - #region IDataCollectionLogger Members - - void IDataCollectionLogger.LogError(DataCollectionContext context, Exception exception) - { - this.wrapped.LogError(context, exception); - } - - void IDataCollectionLogger.LogError(DataCollectionContext context, string text) - { - this.wrapped.LogError(context, text); - } - - void IDataCollectionLogger.LogError(DataCollectionContext context, string text, Exception exception) - { - this.wrapped.LogError(context, text, exception); - } - - void IDataCollectionLogger.LogWarning(DataCollectionContext context, string text) - { - this.wrapped.LogWarning(context, text); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionSinkWrapper.cs b/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionSinkWrapper.cs deleted file mode 100644 index 8b65ae14af..0000000000 --- a/src/DataCollectors/TraceDataCollector/DataCollection/DataCollectionSinkWrapper.cs +++ /dev/null @@ -1,48 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System.ComponentModel; - using TestPlatform.ObjectModel.DataCollection; - - /// - internal sealed class DataCollectionSinkWrapper : IDataCollectionSink - { - private readonly DataCollectionSink wrapped; - - public DataCollectionSinkWrapper(DataCollectionSink wrapped) - { - this.wrapped = wrapped; - } - - #region IDataCollectionSink Members - - event AsyncCompletedEventHandler IDataCollectionSink.SendFileCompleted - { - add { this.wrapped.SendFileCompleted += value; } - remove { this.wrapped.SendFileCompleted -= value; } - } - - void IDataCollectionSink.SendFileAsync(DataCollectionContext context, string path, bool deleteFile) - { - this.wrapped.SendFileAsync(context, path, deleteFile); - } - - void IDataCollectionSink.SendFileAsync( - DataCollectionContext context, - string path, - string description, - bool deleteFile) - { - this.wrapped.SendFileAsync(context, path, description, deleteFile); - } - - void IDataCollectionSink.SendFileAsync(FileTransferInformation fileInformation) - { - this.wrapped.SendFileAsync(fileInformation); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionAgentContext.cs b/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionAgentContext.cs deleted file mode 100644 index a233a03c64..0000000000 --- a/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionAgentContext.cs +++ /dev/null @@ -1,16 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using TestPlatform.ObjectModel.DataCollection; - - /// - /// Wrapper for - /// to make the collector testable. - /// - internal interface IDataCollectionAgentContext - { - DataCollectionContext SessionDataCollectionContext { get; } - } -} diff --git a/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionEvents.cs b/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionEvents.cs deleted file mode 100644 index 2de2cae522..0000000000 --- a/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionEvents.cs +++ /dev/null @@ -1,23 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System; - using TestPlatform.ObjectModel.DataCollection; - - /// - /// Wrapper for - /// to make the collector testable. - /// - internal interface IDataCollectionEvents - { - event EventHandler SessionEnd; - - event EventHandler SessionStart; - - event EventHandler TestCaseEnd; - - event EventHandler TestCaseStart; - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionLogger.cs b/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionLogger.cs deleted file mode 100644 index 8820acbd01..0000000000 --- a/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionLogger.cs +++ /dev/null @@ -1,23 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System; - using TestPlatform.ObjectModel.DataCollection; - - /// - /// Wrapper for - /// to make the collector testable. - /// - internal interface IDataCollectionLogger - { - void LogError(DataCollectionContext context, Exception exception); - - void LogError(DataCollectionContext context, string text); - - void LogError(DataCollectionContext context, string text, Exception exception); - - void LogWarning(DataCollectionContext context, string text); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionSink.cs b/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionSink.cs deleted file mode 100644 index 654922f97b..0000000000 --- a/src/DataCollectors/TraceDataCollector/DataCollection/Interfaces/IDataCollectionSink.cs +++ /dev/null @@ -1,23 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System.ComponentModel; - using TestPlatform.ObjectModel.DataCollection; - - /// - /// Wrapper for - /// to make the collector testable. - /// - internal interface IDataCollectionSink - { - event AsyncCompletedEventHandler SendFileCompleted; - - void SendFileAsync(DataCollectionContext context, string path, bool deleteFile); - - void SendFileAsync(DataCollectionContext context, string path, string displayName, bool deleteFile); - - void SendFileAsync(FileTransferInformation fileInformation); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/DirectoryHelper.cs b/src/DataCollectors/TraceDataCollector/DirectoryHelper.cs deleted file mode 100644 index a4db2d8a68..0000000000 --- a/src/DataCollectors/TraceDataCollector/DirectoryHelper.cs +++ /dev/null @@ -1,30 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System.IO; - using Interfaces; - - /// - internal class DirectoryHelper : IDirectoryHelper - { - /// - public void Delete(string path, bool recursive) - { - Directory.Delete(path, recursive); - } - - /// - public void CreateDirectory(string path) - { - Directory.CreateDirectory(path); - } - - /// - public bool Exists(string path) - { - return Directory.Exists(path); - } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/FileHelper.cs b/src/DataCollectors/TraceDataCollector/FileHelper.cs deleted file mode 100644 index 936a93a9a3..0000000000 --- a/src/DataCollectors/TraceDataCollector/FileHelper.cs +++ /dev/null @@ -1,24 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System.IO; - using Interfaces; - - /// - internal class FileHelper : IFileHelper - { - /// - public bool Exists(string path) - { - return File.Exists(path); - } - - /// - public void WriteAllText(string path, string contents) - { - File.WriteAllText(path, contents); - } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Friends.cs b/src/DataCollectors/TraceDataCollector/Friends.cs deleted file mode 100644 index 10045b5dd3..0000000000 --- a/src/DataCollectors/TraceDataCollector/Friends.cs +++ /dev/null @@ -1,8 +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; - -[assembly: InternalsVisibleTo("Microsoft.TestPlatform.TraceDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] - -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/src/DataCollectors/TraceDataCollector/Interfaces/IDirectoryHelper.cs b/src/DataCollectors/TraceDataCollector/Interfaces/IDirectoryHelper.cs deleted file mode 100644 index 3f50af1ce7..0000000000 --- a/src/DataCollectors/TraceDataCollector/Interfaces/IDirectoryHelper.cs +++ /dev/null @@ -1,32 +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. - -namespace Microsoft.VisualStudio.TraceCollector.Interfaces -{ - /// - /// Interface to Abstract System.IO.Directory methods for mocking in unit tests. - /// - internal interface IDirectoryHelper - { - /// - /// Deletes the specified directory and, if indicated, any subdirectories and files in the directory. - /// - /// The name of the directory to remove. - /// true to remove directories, subdirectories, and files in path; otherwise, false. - void Delete(string path, bool recursive); - - /// - /// Creates all directories and subdirectories in the specified path unless they already exist. - /// - /// The directory to create. - void CreateDirectory(string path); - - /// - /// Determines whether the given path refers to an existing directory on disk. - /// - /// The path to test. - /// true if path refers to an existing directory; - /// false if the directory does not exist or an error occurs when trying to determine if the specified directory exists. - bool Exists(string path); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Interfaces/IEnvironment.cs b/src/DataCollectors/TraceDataCollector/Interfaces/IEnvironment.cs deleted file mode 100644 index 7ed0e044e2..0000000000 --- a/src/DataCollectors/TraceDataCollector/Interfaces/IEnvironment.cs +++ /dev/null @@ -1,16 +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. - -namespace Microsoft.VisualStudio.TraceCollector.Interfaces -{ - /// - /// Operating system environment abstractions. - /// - internal interface IEnvironment - { - /// - /// Gets operating System. - /// - PlatformOperatingSystem OperatingSystem { get; } - } -} diff --git a/src/DataCollectors/TraceDataCollector/Interfaces/IFileHelper.cs b/src/DataCollectors/TraceDataCollector/Interfaces/IFileHelper.cs deleted file mode 100644 index 46e5a4fe7b..0000000000 --- a/src/DataCollectors/TraceDataCollector/Interfaces/IFileHelper.cs +++ /dev/null @@ -1,29 +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. - -namespace Microsoft.VisualStudio.TraceCollector.Interfaces -{ - /// - /// Interface to Abstract System.IO.File methods for mocking in unit tests. - /// - internal interface IFileHelper - { - /// - /// Determines whether the specified file exists. - /// - /// The file to check. - /// true if the caller has the required permissions and path contains the name of an existing file; otherwise, false. - /// This method also returns false if path is null, an invalid path, or a zero-length string. - /// If the caller does not have sufficient permissions to read the specified file, - /// no exception is thrown and the method returns false regardless of the existence of path. - bool Exists(string path); - - /// - /// Creates a new file, writes the specified string to the file, and then closes the file. - /// If the target file already exists, it is overwritten. - /// - /// The file to write to. - /// The string to write to the file. - void WriteAllText(string path, string contents); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Interfaces/IProcessJobObject.cs b/src/DataCollectors/TraceDataCollector/Interfaces/IProcessJobObject.cs deleted file mode 100644 index e5ab73ab8d..0000000000 --- a/src/DataCollectors/TraceDataCollector/Interfaces/IProcessJobObject.cs +++ /dev/null @@ -1,22 +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. - -namespace Microsoft.VisualStudio.TraceCollector.Interfaces -{ - using System; - - /// - /// Helper interface used to add a child process to a job object so that it terminates when - /// the parent process dies - /// - /// An interface to the Windows Job Objects API. - internal interface IProcessJobObject : IDisposable - { - /// - /// Helper function to add a process to the job object - /// - /// Handle of the process to be added - /// - void AddProcess(IntPtr handle); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Interfaces/PlatformOperationSystem.cs b/src/DataCollectors/TraceDataCollector/Interfaces/PlatformOperationSystem.cs deleted file mode 100644 index 6888d8a4fc..0000000000 --- a/src/DataCollectors/TraceDataCollector/Interfaces/PlatformOperationSystem.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. - -namespace Microsoft.VisualStudio.TraceCollector.Interfaces -{ - /// - /// Available operating systems. - /// - internal enum PlatformOperatingSystem - { - Windows, - Unix - } -} diff --git a/src/DataCollectors/TraceDataCollector/Microsoft.VisualStudio.TraceDataCollector.csproj b/src/DataCollectors/TraceDataCollector/Microsoft.VisualStudio.TraceDataCollector.csproj deleted file mode 100644 index ddc4444ce0..0000000000 --- a/src/DataCollectors/TraceDataCollector/Microsoft.VisualStudio.TraceDataCollector.csproj +++ /dev/null @@ -1,51 +0,0 @@ - - - - ..\..\..\ - - - - Microsoft.VisualStudio.TraceDataCollector - netstandard2.0 - true - true - - - - - - - - - - - - - - - - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - True - True - Resources.resx - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - diff --git a/src/DataCollectors/TraceDataCollector/PlatformEnvironment.cs b/src/DataCollectors/TraceDataCollector/PlatformEnvironment.cs deleted file mode 100644 index 7d783f644d..0000000000 --- a/src/DataCollectors/TraceDataCollector/PlatformEnvironment.cs +++ /dev/null @@ -1,26 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System.Runtime.InteropServices; - using Interfaces; - - /// - internal class PlatformEnvironment : IEnvironment - { - /// - public PlatformOperatingSystem OperatingSystem - { - get - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return PlatformOperatingSystem.Windows; - } - - return PlatformOperatingSystem.Unix; - } - } - } -} diff --git a/src/DataCollectors/TraceDataCollector/ProcessJobObject.cs b/src/DataCollectors/TraceDataCollector/ProcessJobObject.cs deleted file mode 100644 index b44164204a..0000000000 --- a/src/DataCollectors/TraceDataCollector/ProcessJobObject.cs +++ /dev/null @@ -1,875 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System; - using System.Runtime.InteropServices; - using Interfaces; - using TestPlatform.ObjectModel; - - /// - /// Helper class used to add a child process to a job object so that it terminates when - /// the parent process dies - /// - /// An interface to the Windows Job Objects API. - internal class ProcessJobObject : IProcessJobObject - { - #region Native 32/64 Bit Switching Flag - - /// - /// The structures returned by Windows are different sizes depending on whether - /// the operating system is running in 32bit or 64bit mode. - /// - private static readonly bool Is32Bit = IntPtr.Size == 4; - - #endregion - - /// - /// Job handle created by the CreateJobObject - /// - private IntPtr jobHandle; - - /// - /// Set to true when disposed - /// - private volatile bool disposed; - - /// - /// Initializes a new instance of the class. - /// Creates a job object - /// - /// Handle to the job object created - public ProcessJobObject() - { - this.CreateJobObject(); - } - - /// - /// Finalizes an instance of the class. - /// - ~ProcessJobObject() - { - this.Dispose(false); - } - - #region JobObjectInfoClass Enumeration - - /// - /// Information class for the limits to be set. This parameter can be one of - /// the following values. - /// - private enum JobObjectInfoClass - { - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_BASIC_ACCOUNTING_INFORMATION structure. - /// - BasicAccountingInformation = 1, - - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_BASIC_LIMIT_INFORMATION structure. - /// - BasicLimitInformation = 2, - - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_BASIC_PROCESS_ID_LIST structure. - /// - BasicProcessIdList = 3, - - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_BASIC_UI_RESTRICTIONS structure. - /// - BasicUIRestrictions = 4, - - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_SECURITY_LIMIT_INFORMATION structure. - /// The hJob handle must have the JOB_OBJECT_SET_SECURITY_ATTRIBUTES - /// access right associated with it. - /// - SecurityLimitInformation = 5, - - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure. - /// - EndOfJobTimeInformation = 6, - - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_ASSOCIATE_COMPLETION_PORT structure. - /// - AssociateCompletionPortInformation = 7, - - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION structure. - /// - BasicAndIoAccountingInformation = 8, - - /// - /// The lpJobObjectInfo parameter is a pointer to a - /// JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. - /// - ExtendedLimitInformation = 9 - } - - #endregion - - #region LimitFlags Enumeration - - /// - /// Limit flags that are in effect. This member is a bit field that determines - /// whether other structure members are used. Any combination of the following - /// values can be specified. - /// - [Flags] - private enum LimitFlags - { - /// - /// Causes all processes associated with the job to use the same minimum and maximum working set sizes. - /// - LimitWorkingSet = 0x00000001, - - /// - /// Establishes a user-mode execution time limit for each currently active process - /// and for all future processes associated with the job. - /// - LimitProcessTime = 0x00000002, - - /// - /// Establishes a user-mode execution time limit for the job. This flag cannot - /// be used with JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME. - /// - LimitJobTime = 0x00000004, - - /// - /// Establishes a maximum number of simultaneously active processes associated - /// with the job. - /// - LimitActiveProcesses = 0x00000008, - - /// - /// Causes all processes associated with the job to use the same processor - /// affinity. - /// - LimitAffinity = 0x00000010, - - /// - /// Causes all processes associated with the job to use the same priority class. - /// For more information, see Scheduling Priorities. - /// - LimitPriorityClass = 0x00000020, - - /// - /// Preserves any job time limits you previously set. As long as this flag is - /// set, you can establish a per-job time limit once, then alter other limits - /// in subsequent calls. This flag cannot be used with JOB_OBJECT_LIMIT_JOB_TIME. - /// - PreserveJobTime = 0x00000040, - - /// - /// Causes all processes in the job to use the same scheduling class. - /// - LimitSchedulingClass = 0x00000080, - - /// - /// Causes all processes associated with the job to limit their committed memory. - /// When a process attempts to commit memory that would exceed the per-process - /// limit, it fails. If the job object is associated with a completion port, a - /// JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT message is sent to the completion port. - /// This limit requires use of a JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. - /// Its BasicLimitInformation member is a JOBOBJECT_BASIC_LIMIT_INFORMATION - /// structure. - /// - LimitProcessMemory = 0x00000100, - - /// - /// Causes all processes associated with the job to limit the job-wide sum of - /// their committed memory. When a process attempts to commit memory that would - /// exceed the job-wide limit, it fails. If the job object is associated with a - /// completion port, a JOB_OBJECT_MSG_JOB_MEMORY_LIMIT message is sent to the - /// completion port. This limit requires use of a - /// JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. Its BasicLimitInformation - /// member is a JOBOBJECT_BASIC_LIMIT_INFORMATION structure. - /// - LimitJobMemory = 0x00000200, - - /// - /// Forces a call to the SetErrorMode function with the SEM_NOGPFAULTERRORBOX - /// flag for each process associated with the job. If an exception occurs and - /// the system calls the UnhandledExceptionFilter function, the debugger will - /// be given a chance to act. If there is no debugger, the functions returns - /// EXCEPTION_EXECUTE_HANDLER. Normally, this will cause termination of the - /// process with the exception code as the exit status. This limit requires - /// use of a JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. Its - /// BasicLimitInformation member is a JOBOBJECT_BASIC_LIMIT_INFORMATION structure. - /// - DieOnUnhandledException = 0x00000400, - - /// - /// If any process associated with the job creates a child process using the - /// CREATE_BREAKAWAY_FROM_JOB flag while this limit is in effect, the child - /// process is not associated with the job. This limit requires use of a - /// JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. Its BasicLimitInformation - /// member is a JOBOBJECT_BASIC_LIMIT_INFORMATION structure. - /// - LimitBreakawayOk = 0x00000800, - - /// - /// Allows any process associated with the job to create child processes - /// that are not associated with the job. This limit requires use of a - /// JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. Its BasicLimitInformation - /// member is a JOBOBJECT_BASIC_LIMIT_INFORMATION structure. - /// - LimitSilentBreakawayOk = 0x00001000, - - /// - /// Causes all processes associated with the job to terminate when the last - /// handle to the job is closed. This limit requires use of a - /// JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure. Its BasicLimitInformation - /// member is a JOBOBJECT_BASIC_LIMIT_INFORMATION structure. - /// Windows 2000: This flag is not supported. - /// - LimitKillOnJobClose = 0x00002000 - } - - #endregion - - /// - /// Helper function to add a process to the job object - /// - /// Handle of the process to be added - public void AddProcess(IntPtr handle) - { - if (this.jobHandle != IntPtr.Zero) - { - if (!WinAPI.AssignProcessToJobObject(this.jobHandle, handle)) - { - EqtTrace.Warning("AddProcess : Failed to AddProcess {0}", Marshal.GetLastWin32Error()); - } - } - else - { - EqtTrace.Warning("AddProcess : Ignoring as job object is not created"); - } - } - - /// - /// Dispose the resources - /// - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - #region Private Members - - /// - /// Helper function to create job object - /// - private void CreateJobObject() - { - this.jobHandle = WinAPI.CreateJobObject(IntPtr.Zero, null); - if (this.jobHandle == IntPtr.Zero) - { - EqtTrace.Warning("CreateJobObject : Failed {0}", Marshal.GetLastWin32Error()); - } - - if (ProcessJobObject.Is32Bit) - { - BasicLimits32 basicInfo = default(BasicLimits32); - basicInfo.LimitFlags = LimitFlags.LimitKillOnJobClose; - - ExtendedLimits32 extendedInfo = default(ExtendedLimits32); - extendedInfo.BasicLimits = basicInfo; - - JobObjectInfo info = default(JobObjectInfo); - info.basicLimits32 = basicInfo; - info.extendedLimits32 = extendedInfo; - - if (!WinAPI.SetInformationJobObject( - this.jobHandle, - JobObjectInfoClass.ExtendedLimitInformation, - ref info, - Marshal.SizeOf())) - { - EqtTrace.Warning("CreateJobObject [32] : Failed to setInformation {0}", Marshal.GetLastWin32Error()); - } - } - else - { - BasicLimits64 basicInfo = default(BasicLimits64); - basicInfo.LimitFlags = LimitFlags.LimitKillOnJobClose; - - ExtendedLimits64 extendedInfo = default(ExtendedLimits64); - extendedInfo.BasicLimits = basicInfo; - - JobObjectInfo info = default(JobObjectInfo); - info.basicLimits64 = basicInfo; - info.extendedLimits64 = extendedInfo; - - if (!WinAPI.SetInformationJobObject( - this.jobHandle, - JobObjectInfoClass.ExtendedLimitInformation, - ref info, - Marshal.SizeOf())) - { - EqtTrace.Warning("CreateJobObject [64] : Failed to setInformation {0}", Marshal.GetLastWin32Error()); - } - } - } - - /// - /// Helper function to dispose managed and unmanaged resources - /// - /// The disposing. - private void Dispose(bool disposing) - { - bool isDisposed = this.disposed; - if (!isDisposed) - { - this.disposed = true; - if (disposing) - { - // Managed resources - } - - if (this.jobHandle != IntPtr.Zero) - { - WinAPI.CloseHandle(this.jobHandle); - } - } - } - - #endregion - - #region IoCounters Structures - - /// - /// Various counters for different types of IO operations - /// - [StructLayout(LayoutKind.Explicit)] - private struct IoCounters32 - { - /// - /// The number of read operations. - /// - [FieldOffset(0)] - public ulong ReadOperationCount; - - /// - /// The number of write operations. - /// - [FieldOffset(8)] - public ulong WriteOperationCount; - - /// - /// The number of other operations. - /// - [FieldOffset(16)] - public ulong OtherOperationCount; - - /// - /// The number of read transfers. - /// - [FieldOffset(24)] - public ulong ReadTransferCount; - - /// - /// The number of write transfers. - /// - [FieldOffset(32)] - public ulong WriteTransferCount; - - /// - /// The number of other transfers. - /// - [FieldOffset(40)] - public ulong OtherTransferCount; - } - - /// - /// Various counters for different types of IO operations. - /// - [StructLayout(LayoutKind.Explicit)] - private struct IoCounters64 - { - /// - /// The number of read operations. - /// - [FieldOffset(0)] - public ulong ReadOperationCount; - - /// - /// The number of write operations. - /// - [FieldOffset(8)] - public ulong WriteOperationCount; - - /// - /// The number of other operations. - /// - [FieldOffset(16)] - public ulong OtherOperationCount; - - /// - /// The number of read transfers. - /// - [FieldOffset(24)] - public ulong ReadTransferCount; - - /// - /// The number of write transfers. - /// - [FieldOffset(32)] - public ulong WriteTransferCount; - - /// - /// The number of other transfers. - /// - [FieldOffset(40)] - public ulong OtherTransferCount; - } - - #endregion - - #region BasicLimits Structures - - /// - /// The JOBOBJECT_BASIC_LIMIT_INFORMATION structure contains basic limit - /// information for a job object. - /// - [StructLayout(LayoutKind.Explicit)] - private struct BasicLimits32 - { - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_PROCESS_TIME, this member is - /// the per-process user-mode execution time limit, in 100-nanosecond ticks. - /// Otherwise, this member is ignored. The system periodically checks to - /// determine whether each process associated with the job has accumulated - /// more user-mode time than the set limit. If it has, the process is terminated. - /// - [FieldOffset(0)] - public long PerProcessUserTimeLimit; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_JOB_TIME, this member is the - /// per-job user-mode execution time limit, in 100-nanosecond ticks. Otherwise, - /// this member is ignored. The system adds the current time of the processes - /// associated with the job to this limit. For example, if you set this limit - /// to 1 minute, and the job has a process that has accumulated 5 minutes of - /// user-mode time, the limit actually enforced is 6 minutes. The system - /// periodically checks to determine whether the sum of the user-mode execution - /// time for all processes is greater than this end-of-job limit. If it is, the - /// action specified in the EndOfJobTimeAction member of the - /// JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure is carried out. By default, - /// all processes are terminated and the status code is set to - /// ERROR_NOT_ENOUGH_QUOTA. - /// - [FieldOffset(8)] - public long PerJobUserTimeLimit; - - /// - /// Limit flags that are in effect. This member is a bit field that determines - /// whether other structure members are used. Any combination LimitFlag values - /// can be specified. - /// - [FieldOffset(16)] - public LimitFlags LimitFlags; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_WORKINGSET, this member is the - /// minimum working set size for each process associated with the job. Otherwise, - /// this member is ignored. If MaximumWorkingSetSize is nonzero, - /// MinimumWorkingSetSize cannot be zero. - /// - [FieldOffset(20)] - public uint MinimumWorkingSetSize; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_WORKINGSET, this member is the - /// maximum working set size for each process associated with the job. Otherwise, - /// this member is ignored. If MinimumWorkingSetSize is nonzero, - /// MaximumWorkingSetSize cannot be zero. - /// - [FieldOffset(24)] - public uint MaximumWorkingSetSize; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_ACTIVE_PROCESS, this member is the - /// active process limit for the job. Otherwise, this member is ignored. If you - /// try to associate a process with a job, and this causes the active process - /// count to exceed this limit, the process is terminated and the association - /// fails. - /// - [FieldOffset(28)] - public int ActiveProcessLimit; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_AFFINITY, this member is the - /// processor affinity for all processes associated with the job. Otherwise, - /// this member is ignored. The affinity must be a proper subset of the system - /// affinity mask obtained by calling the GetProcessAffinityMask function. The - /// affinity of each thread is set to this value, but threads are free to - /// subsequently set their affinity, as long as it is a subset of the specified - /// affinity mask. Processes cannot set their own affinity mask. - /// - [FieldOffset(32)] - public IntPtr Affinity; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_PRIORITY_CLASS, this member is the - /// priority class for all processes associated with the job. Otherwise, this - /// member is ignored. Processes and threads cannot modify their priority class. - /// The calling process must enable the SE_INC_BASE_PRIORITY_NAME privilege. - /// - [FieldOffset(36)] - public int PriorityClass; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_SCHEDULING_CLASS, this member is - /// the scheduling class for all processes associated with the job. Otherwise, - /// this member is ignored. The valid values are 0 to 9. Use 0 for the least - /// favorable scheduling class relative to other threads, and 9 for the most - /// favorable scheduling class relative to other threads. By default, this - /// value is 5. To use a scheduling class greater than 5, the calling process - /// must enable the SE_INC_BASE_PRIORITY_NAME privilege. - /// - [FieldOffset(40)] - public int SchedulingClass; - } - - /// - /// The JOBOBJECT_BASIC_LIMIT_INFORMATION structure contains basic limit - /// information for a job object. - /// - [StructLayout(LayoutKind.Explicit)] - private struct BasicLimits64 - { - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_PROCESS_TIME, this member is - /// the per-process user-mode execution time limit, in 100-nanosecond ticks. - /// Otherwise, this member is ignored. The system periodically checks to - /// determine whether each process associated with the job has accumulated - /// more user-mode time than the set limit. If it has, the process is terminated. - /// - [FieldOffset(0)] - public long PerProcessUserTimeLimit; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_JOB_TIME, this member is the - /// per-job user-mode execution time limit, in 100-nanosecond ticks. Otherwise, - /// this member is ignored. The system adds the current time of the processes - /// associated with the job to this limit. For example, if you set this limit - /// to 1 minute, and the job has a process that has accumulated 5 minutes of - /// user-mode time, the limit actually enforced is 6 minutes. The system - /// periodically checks to determine whether the sum of the user-mode execution - /// time for all processes is greater than this end-of-job limit. If it is, the - /// action specified in the EndOfJobTimeAction member of the - /// JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure is carried out. By default, - /// all processes are terminated and the status code is set to - /// ERROR_NOT_ENOUGH_QUOTA. - /// - [FieldOffset(8)] - public long PerJobUserTimeLimit; - - /// - /// Limit flags that are in effect. This member is a bit field that determines - /// whether other structure members are used. Any combination LimitFlag values - /// can be specified. - /// - [FieldOffset(16)] - public LimitFlags LimitFlags; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_WORKINGSET, this member is the - /// minimum working set size for each process associated with the job. Otherwise, - /// this member is ignored. If MaximumWorkingSetSize is nonzero, - /// MinimumWorkingSetSize cannot be zero. - /// - [FieldOffset(24)] - public ulong MinimumWorkingSetSize; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_WORKINGSET, this member is the - /// maximum working set size for each process associated with the job. Otherwise, - /// this member is ignored. If MinimumWorkingSetSize is nonzero, - /// MaximumWorkingSetSize cannot be zero. - /// - [FieldOffset(32)] - public ulong MaximumWorkingSetSize; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_ACTIVE_PROCESS, this member is the - /// active process limit for the job. Otherwise, this member is ignored. If you - /// try to associate a process with a job, and this causes the active process - /// count to exceed this limit, the process is terminated and the association - /// fails. - /// - [FieldOffset(40)] - public int ActiveProcessLimit; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_AFFINITY, this member is the - /// processor affinity for all processes associated with the job. Otherwise, - /// this member is ignored. The affinity must be a proper subset of the system - /// affinity mask obtained by calling the GetProcessAffinityMask function. The - /// affinity of each thread is set to this value, but threads are free to - /// subsequently set their affinity, as long as it is a subset of the specified - /// affinity mask. Processes cannot set their own affinity mask. - /// - [FieldOffset(48)] - public IntPtr Affinity; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_PRIORITY_CLASS, this member is the - /// priority class for all processes associated with the job. Otherwise, this - /// member is ignored. Processes and threads cannot modify their priority class. - /// The calling process must enable the SE_INC_BASE_PRIORITY_NAME privilege. - /// - [FieldOffset(56)] - public int PriorityClass; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_SCHEDULING_CLASS, this member is - /// the scheduling class for all processes associated with the job. Otherwise, - /// this member is ignored. The valid values are 0 to 9. Use 0 for the least - /// favorable scheduling class relative to other threads, and 9 for the most - /// favorable scheduling class relative to other threads. By default, this - /// value is 5. To use a scheduling class greater than 5, the calling process - /// must enable the SE_INC_BASE_PRIORITY_NAME privilege. - /// - [FieldOffset(60)] - public int SchedulingClass; - } - #endregion - - #region ExtendedLimits Structures - - /// - /// The JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure contains basic and extended limit - /// information for a job object. - /// - [StructLayout(LayoutKind.Explicit)] - private struct ExtendedLimits32 - { - /// - /// A JOBOBJECT_BASIC_LIMIT_INFORMATION structure that contains - /// basic limit information. - /// - [FieldOffset(0)] - public BasicLimits32 BasicLimits; - - /// - /// Reserved. - /// - [FieldOffset(48)] - public IoCounters32 IoInfo; - - /// - /// If the LimitFlags member of the JOBOBJECT_BASIC_LIMIT_INFORMATION structure - /// specifies the JOB_OBJECT_LIMIT_PROCESS_MEMORY value, this member specifies - /// the limit for the virtual memory that can be committed by a process. - /// Otherwise, this member is ignored. - /// - [FieldOffset(96)] - public uint ProcessMemoryLimit; - - /// - /// If the LimitFlags member of the JOBOBJECT_BASIC_LIMIT_INFORMATION structure - /// specifies the JOB_OBJECT_LIMIT_JOB_MEMORY value, this member specifies the - /// limit for the virtual memory that can be committed for the job. Otherwise, - /// this member is ignored. - /// - [FieldOffset(100)] - public uint JobMemoryLimit; - - /// - /// Peak memory used by any process ever associated with the job. - /// - [FieldOffset(104)] - public uint PeakProcessMemoryUsed; - - /// - /// Peak memory usage of all processes currently associated with the job. - /// - [FieldOffset(108)] - public uint PeakJobMemoryUsed; - } - - /// - /// The JOBOBJECT_EXTENDED_LIMIT_INFORMATION structure contains basic and extended limit - /// information for a job object. - /// - [StructLayout(LayoutKind.Explicit)] - private struct ExtendedLimits64 - { - /// - /// A JOBOBJECT_BASIC_LIMIT_INFORMATION structure that contains - /// basic limit information. - /// - [FieldOffset(0)] - public BasicLimits64 BasicLimits; - - /// - /// Reserved. - /// - [FieldOffset(64)] - public IoCounters64 IoInfo; - - /// - /// If the LimitFlags member of the JOBOBJECT_BASIC_LIMIT_INFORMATION structure - /// specifies the JOB_OBJECT_LIMIT_PROCESS_MEMORY value, this member specifies - /// the limit for the virtual memory that can be committed by a process. - /// Otherwise, this member is ignored. - /// - [FieldOffset(112)] - public ulong ProcessMemoryLimit; - - /// - /// If the LimitFlags member of the JOBOBJECT_BASIC_LIMIT_INFORMATION structure - /// specifies the JOB_OBJECT_LIMIT_JOB_MEMORY value, this member specifies the - /// limit for the virtual memory that can be committed for the job. Otherwise, - /// this member is ignored. - /// - [FieldOffset(120)] - public ulong JobMemoryLimit; - - /// - /// Peak memory used by any process ever associated with the job. - /// - [FieldOffset(128)] - public ulong PeakProcessMemoryUsed; - - /// - /// Peak memory usage of all processes currently associated with the job. - /// - [FieldOffset(136)] - public ulong PeakJobMemoryUsed; - } - #endregion - - #region JobObjectInfo Union - -#pragma warning disable SA1307 // Accessible fields must begin with upper-case letter - - /// - /// Union of different limit data structures that may be passed - /// to SetInformationJobObject / from QueryInformationJobObject. - /// This union also contains separate 32 and 64 bit versions of - /// each structure. - /// - [StructLayout(LayoutKind.Explicit)] - private struct JobObjectInfo - { - #region 32 bit structures - - /// - /// The BasicLimits32 structure contains basic limit information - /// for a job object on a 32bit platform. - /// - [FieldOffset(0)] - public BasicLimits32 basicLimits32; - - /// - /// The ExtendedLimits32 structure contains extended limit information - /// for a job object on a 32bit platform. - /// - [FieldOffset(0)] - - public ExtendedLimits32 extendedLimits32; - - #endregion - - #region 64 bit structures - - /// - /// The BasicLimits64 structure contains basic limit information - /// for a job object on a 64bit platform. - /// - [FieldOffset(0)] - public BasicLimits64 basicLimits64; - - /// - /// The ExtendedLimits64 structure contains extended limit information - /// for a job object on a 64bit platform. - /// - [FieldOffset(0)] - public ExtendedLimits64 extendedLimits64; - - #endregion - } - - #endregion - -#pragma warning restore SA1307 // Accessible fields must begin with upper-case letter - - #region IDisposable implementation - - #endregion - - #region WinAPI Class - - /// - /// Private class that holds all the Windows API calls made by this - /// - private class WinAPI - { - /// - /// The CreateJobObject function creates or opens a job object. - /// - /// Pointer to a SECURITY_ATTRIBUTES structure - /// Pointer to a null-terminated string specifying the name of the job. - /// If the function succeeds, the return value is a handle to the job object - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr CreateJobObject(IntPtr jobAttributes, string name); - - /// - /// The AssignProcessToJobObject function assigns a process to an existing job object. - /// - /// Handle to the job object to which the process will be associated. - /// Handle to the process to associate with the job object - /// If the function succeeds, the return value is nonzero - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool AssignProcessToJobObject(IntPtr jobHandle, IntPtr processHandle); - - /// - /// The SetInformationJobObject function sets limits for a job object. - /// - /// Handle to the job whose limits are being set. - /// Information class for the limits to be set. This - /// parameter can be one of the following values. - /// Limits to be set for the job. The format of this data - /// depends on the value of JobObjectInfoClass. - /// Size of the job information being set, in - /// bytes. - /// If the function succeeds, the return value is nonzero. If the function - /// fails, the return value is zero. To get extended error information, - /// call GetLastError. - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool SetInformationJobObject( - [In] IntPtr jobHandle, - [In] JobObjectInfoClass jobObjectInfoClass, - [In] ref JobObjectInfo jobObjectInfo, - [In] int jobObjectInfoLength); - - /// - /// The CloseHandle function lets us destroy a JobObject handle. - /// - /// Handle to the job - /// If the function succeeds, the return value true. If the function - /// fails, the return value is false. To get extended error information, - /// call GetLastError. - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool CloseHandle([In] IntPtr jobHandle); - } - - #endregion - } -} diff --git a/src/DataCollectors/TraceDataCollector/Properties/AssemblyInfo.cs b/src/DataCollectors/TraceDataCollector/Properties/AssemblyInfo.cs deleted file mode 100644 index 348b5dcdfc..0000000000 --- a/src/DataCollectors/TraceDataCollector/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,27 +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.Reflection; -using System.Runtime.InteropServices; - -using Microsoft.VisualStudio.Coverage; -using Microsoft.VisualStudio.TestPlatform; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft Corporation")] -[assembly: AssemblyCopyright(" Microsoft Corporation. All rights reserved.")] -[assembly: AssemblyProduct("Microsoft.VisualStudio.TraceDataCollector")] -[assembly: AssemblyTrademark("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b06e12a5-025f-42aa-8f09-c6666c65ece7")] - -[assembly: TestExtensionTypes(typeof(DynamicCoverageDataCollector))] \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/Resources.Designer.cs b/src/DataCollectors/TraceDataCollector/Resources/Resources.Designer.cs deleted file mode 100644 index e4669a0a8c..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/Resources.Designer.cs +++ /dev/null @@ -1,118 +0,0 @@ -//------------------------------------------------------------------------------ -// -// 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.VisualStudio.TraceDataCollector.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.VisualStudio.TraceDataCollector.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 No code coverage data available. Code coverage is currently supported only on Windows.. - /// - internal static string CodeCoverageOnlySupportsWindows { - get { - return ResourceManager.GetString("CodeCoverageOnlySupportsWindows", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Failed to create directory: {0} with error:{1}. - /// - internal static string FailedToCreateDirectory { - get { - return ResourceManager.GetString("FailedToCreateDirectory", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Failed to initialize code coverage datacollector with error: {0}. - /// - internal static string FailedToInitializeCodeCoverageDataCollector { - get { - return ResourceManager.GetString("FailedToInitializeCodeCoverageDataCollector", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Running event not received from CodeCoverage.exe. Check eventlogs for failure reason.. - /// - internal static string NoRunningEventFromVanguard { - get { - return ResourceManager.GetString("NoRunningEventFromVanguard", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout.. - /// - internal static string VanguardConnectionTimeout { - get { - return ResourceManager.GetString("VanguardConnectionTimeout", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Cannot find CodeCoverage.exe at {0}. - /// - internal static string VanguardNotFound { - get { - return ResourceManager.GetString("VanguardNotFound", resourceCulture); - } - } - } -} diff --git a/src/DataCollectors/TraceDataCollector/Resources/Resources.resx b/src/DataCollectors/TraceDataCollector/Resources/Resources.resx deleted file mode 100644 index bec54d6610..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/Resources.resx +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - - - Failed to create directory: {0} with error:{1} - - - Failed to initialize code coverage datacollector with error: {0} - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - - - Cannot find CodeCoverage.exe at {0} - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - - - No code coverage data available. Code coverage is currently supported only on Windows. - - \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.cs.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.cs.xlf deleted file mode 100644 index eb8fd00b89..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.cs.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - Adresář {0} se nepovedlo vytvořit. Chyba: {1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Od CodeCoverage.exe se nepřijala spuštěná událost. Zkontrolujte důvod selhání v protokolech událostí. - - - - Cannot find CodeCoverage.exe at {0} - Nepovedlo se najít CodeCoverage.exe v {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Za {0} s se nepovedlo získat spuštěnou událost z CodeCoverage.exe. Důvodem může být pomalý počítač. Nastavením proměnné prostředí {1} prosím časový limit prodlužte. - - - - Failed to initialize code coverage datacollector with error: {0} - Nepovedlo se inicializovat kolekci dat pro pokrytí kódu. Chyba: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - Data pokrytí kódu nejsou dostupná. Pokrytí kódu se momentálně podporuje jenom ve Windows. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.de.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.de.xlf deleted file mode 100644 index e2b8f978e6..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.de.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - Fehler beim Erstellen des Verzeichnisses "{0}": {1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Das ausgeführte Ereignis wurde von "CodeCoverage.exe" nicht erhalten. Suchen Sie in den Ereignisprotokollen nach der Fehlerursache. - - - - Cannot find CodeCoverage.exe at {0} - "CodeCoverage.exe" wurde unter "{0}" nicht gefunden. - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Fehler beim Abrufen des ausgeführten Ereignisses von "CodeCoverage.exe" nach {0} Sekunden. Möglicherweise ist der Computer langsam. Legen Sie die Umgebungsvariable "{1}" fest, um den Timeoutwert zu erhöhen. - - - - Failed to initialize code coverage datacollector with error: {0} - Fehler beim Initialisieren des Code Coverage-Datensammlers: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - Es sind keine Code Coverage-Daten verfügbar. Code Coverage wird zurzeit nur unter Windows unterstützt. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.es.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.es.xlf deleted file mode 100644 index c9b840ad99..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.es.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - No se pudo crear el directorio {0} debido al error {1}. - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - No se recibió el evento en ejecución de CodeCoverage.exe. Compruebe los registros del evento para ver el motivo del error. - - - - Cannot find CodeCoverage.exe at {0} - No se encuentra el archivo CodeCoverage.exe en {0}. - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - No se pudo recibir el evento en ejecución de CodeCoverage.exe en {0} segundos. Esto puede deberse a la lentitud de la máquina. Configure la variable de entorno {1} para aumentar el tiempo de espera. - - - - Failed to initialize code coverage datacollector with error: {0} - No se pudo inicializar el recopilador de datos de la cobertura de código debido al error {0}. - - - - No code coverage data available. Code coverage is currently supported only on Windows. - No hay datos de la cobertura de código disponibles. La cobertura de código solo se admite en Windows actualmente. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.fr.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.fr.xlf deleted file mode 100644 index 4df9ff3fc7..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.fr.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - Échec de la création du répertoire : {0} avec l’erreur :{1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Événement en cours d’exécution non reçu de CodeCoverage.exe. Pour en connaître la raison, consultez les journaux des événements. - - - - Cannot find CodeCoverage.exe at {0} - CodeCoverage.exe introuvable à l’emplacement {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Impossible de recevoir l’événement en cours d’exécution de CodeCoverage.exe en {0} secondes. Cette situation peut se produire à cause de la lenteur de l’ordinateur. Définissez la variable d’environnement {1} de sorte à augmenter le délai d’expiration. - - - - Failed to initialize code coverage datacollector with error: {0} - Échec de l’initialisation du collecteur de données de couverture du code avec l’erreur : {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - Les données de couverture du code ne sont pas disponibles. La couverture du code est actuellement prise en charge uniquement sur Windows. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.it.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.it.xlf deleted file mode 100644 index 410b024a3a..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.it.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - Non è stato possibile creare la directory: {0}. Errore:{1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Evento in esecuzione non ricevuto da CodeCoverage.exe. Per la causa dell'errore, vedere i log eventi. - - - - Cannot find CodeCoverage.exe at {0} - CodeCoverage.exe non è stato trovato in {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Non è stato possibile ricevere l'evento in esecuzione da CodeCoverage.exe in {0} secondi. Questo problema può verificarsi a causa della lentezza del computer. Impostare la variabile di ambiente {1} in modo da incrementare il timeout. - - - - Failed to initialize code coverage datacollector with error: {0} - Non è stato possibile inizializzare l'agente di raccolta dati di code coverage. Errore: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - I dati di code coverage non sono disponibili. Il code coverage è attualmente supportato solo in Windows. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ja.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ja.xlf deleted file mode 100644 index 8be9b701e0..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ja.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - ディレクトリ {0} の作成に失敗しました。エラー: {1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - 実行中イベントが CodeCoverage.exe から受信されません。エラーの原因については、EventLog をご確認ください。 - - - - Cannot find CodeCoverage.exe at {0} - CodeCoverage.exe が次の場所に見つかりません: {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - 実行中イベントを CodeCoverage.exe から {0} 秒以内に受信できませんでした。これは、マシンの遅さが原因で発生する可能性があるため、環境変数 {1} を設定してタイムアウト時間を増やしてください。 - - - - Failed to initialize code coverage datacollector with error: {0} - 次のエラーが原因で、コード カバレッジ データ コレクターを初期化できませんでした: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - コード カバレッジ データを利用できません。現在、コード カバレッジは Windows でのみサポートされています。 - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ko.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ko.xlf deleted file mode 100644 index 4849c97766..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ko.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - 다음 오류가 발생하여 {0} 디렉터리를 만들지 못했습니다.{1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - CodeCoverage.exe에서 실행 중인 이벤트를 받지 못했습니다. 실패 원인은 이벤트 로그를 확인하세요. - - - - Cannot find CodeCoverage.exe at {0} - {0}에서 CodeCoverage.exe를 찾을 수 없습니다. - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - CodeCoverage.exe에서 실행 중인 이벤트를 {0}초 내에 받지 못했습니다. 이런 오류는 컴퓨터가 느려서 발생할 수 있습니다. 환경 변수 {1}을(를) 설정하여 시간 제한을 늘리세요. - - - - Failed to initialize code coverage datacollector with error: {0} - 다음 오류가 발생하여 코드 검사 datacollector를 초기화하지 못했습니다. {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - 사용할 수 있는 코드 검사 데이터가 없습니다. 코드 검사는 현재 Windows에서만 지원됩니다. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.pl.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.pl.xlf deleted file mode 100644 index ead72f590e..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.pl.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - Nie można utworzyć katalogu: {0}. Błąd: {1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Nie odebrano bieżącego zdarzenia z pliku CodeCoverage.exe. Sprawdź dziennik zdarzeń, aby poznać przyczynę niepowodzenia. - - - - Cannot find CodeCoverage.exe at {0} - Nie można znaleźć pliku CodeCoverage.exe w lokalizacji {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Nie udało się odebrać bieżącego zdarzenia z programu CodeCoverage.exe w ciągu {0} sek. Przyczyną może być wolne działanie maszyny. Aby zwiększyć limit czasu, ustaw zmienną środowiskową {1}. - - - - Failed to initialize code coverage datacollector with error: {0} - Nie udało się zainicjować modułu zbierającego dane pokrycia kodu. Błąd: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - Dane pokrycia kodu są niedostępne. Pokrycie kodu jest obecnie obsługiwane wyłącznie w systemie Windows. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.pt-BR.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.pt-BR.xlf deleted file mode 100644 index edee3bfe8e..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.pt-BR.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - Falha ao criar o diretório: {0} com erro:{1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Evento de execução não recebido de CodeCoverage.exe. Verifique os logs de eventos para ver o motivo da falha. - - - - Cannot find CodeCoverage.exe at {0} - Não é possível encontrar CodeCoverage.exe em {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Falha ao receber o evento de execução de CodeCoverage.exe em {0} segundo(s). Isso pode ocorrer devido à lentidão do computador. Defina a variável de ambiente {1} para aumentar o tempo limite. - - - - Failed to initialize code coverage datacollector with error: {0} - Falha ao inicializar o datacollector de cobertura do código com o erro: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - Nenhum dado de cobertura do código disponível. A cobertura do código é suportada atualmente apenas no Windows. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ru.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ru.xlf deleted file mode 100644 index aeb81cf9c8..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.ru.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - Не удалось создать каталог {0}, ошибка: {1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Выполняемое событие не получено из CodeCoverage.exe. Причину сбоя см. в журналах событий. - - - - Cannot find CodeCoverage.exe at {0} - Не удается найти CodeCoverage.exe в {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Не удалось получить выполняемое событие из CodeCoverage.exe за {0} с. Возможно, компьютер работает медленно. Увеличьте время ожидания в переменной среды {1}. - - - - Failed to initialize code coverage datacollector with error: {0} - Не удалось инициализировать сборщик данных объема протестированного кода, ошибка: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - Нет доступных данных объема протестированного кода. Определение объема протестированного кода сейчас поддерживается только на Windows. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.tr.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.tr.xlf deleted file mode 100644 index 203d06343f..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.tr.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - {0} dizini şu hatayla oluşturulamadı:{1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Çalıştırılan olay CodeCoverage.exe kaynağından alınamadı. İşlemin başarısız olmasının nedenini öğrenmek için eventlogs verilerini inceleyin. - - - - Cannot find CodeCoverage.exe at {0} - CodeCoverage.exe şu konumda bulunamıyor: {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Çalıştırılan olay CodeCoverage.exe kaynağından {0} saniye içinde alınamadı. Bu durum makinenin yavaşlığından kaynaklanıyor olabilir. Zaman aşımı süresini artırmak için lütfen ortam değişkenini {1} olarak ayarlayın. - - - - Failed to initialize code coverage datacollector with error: {0} - Kod kapsamı veri toplayıcısı şu hata nedeniyle başlatılamadı: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - Kod kapsamı verisi yok. Kod kapsamı şu anda yalnızca Windows’da destekleniyor. - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.xlf deleted file mode 100644 index ac591caaee..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.xlf +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - Failed to create directory: {0} with error:{1} - Failed to create directory: {0} with error:{1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - Running event not received from CodeCoverage.exe in {0} seconds. Check eventlogs for failure reason. This may occur due to machine slowness, please set environment variable {2} to increase timeout. - - - - Cannot find CodeCoverage.exe at {0} - Cannot find CodeCoverage.exe at {0} - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - - - - Failed to initialize code coverage datacollector with error: {0} - Failed to initialize code coverage datacollector with error: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - Currently code coverage support available only for Windows operating system. No code coverage data available for current test run. - - - - - \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.zh-Hans.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.zh-Hans.xlf deleted file mode 100644 index 6fc42aae54..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.zh-Hans.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - 目录 {0} 创建失败,出现错误: {1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - 未收到来自 CodeCoverage.exe 的运行事件。请查看事件日志,了解失败原因。 - - - - Cannot find CodeCoverage.exe at {0} - 无法在 {0} 中找到 CodeCoverage.exe - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - 未能在 {0} 秒内接收到来自 CodeCoverage.exe 的运行事件,出现此问题可能是因为计算机性能较低,请设置环境变量 {1},增加超时时间值。 - - - - Failed to initialize code coverage datacollector with error: {0} - 无法初始化代码覆盖率 datacollector,出现错误: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - 没有可用的代码覆盖率数据。代码覆盖率目前仅在 Windows 上受支持。 - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.zh-Hant.xlf b/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.zh-Hant.xlf deleted file mode 100644 index 4a2b746ab0..0000000000 --- a/src/DataCollectors/TraceDataCollector/Resources/xlf/Resources.zh-Hant.xlf +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- - 119 - 101.15 - 101.15 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 119 - 0 - -
- - - Failed to create directory: {0} with error:{1} - 無法建立目錄: {0},出現錯誤:{1} - - - - Running event not received from CodeCoverage.exe. Check eventlogs for failure reason. - 正在執行並非從 CodeCoverage.exe 接收的事件。請查看事件記錄檔,以了解失敗原因。 - - - - Cannot find CodeCoverage.exe at {0} - 在 {0} 找不到 CodeCoverage.exe - - - - Failed to receive running event from CodeCoverage.exe in {0} seconds, This may occur due to machine slowness, please set environment variable {1} to increase timeout. - 未在 {0} 秒內從 CodeCoverage.exe 收到執行中的事件。可能是因為電腦太慢,請設定環境變數 {1},加長逾時。 - - - - Failed to initialize code coverage datacollector with error: {0} - 無法初始化程式碼涵蓋範圍資料收集器,錯誤為: {0} - - - - No code coverage data available. Code coverage is currently supported only on Windows. - 無任何程式碼涵蓋範圍可用。目前只有在 Windows 上才支援程式碼涵蓋範圍。 - - - -
-
\ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/DefaultCodeCoverageConfig.xml b/src/DataCollectors/TraceDataCollector/VanguardCollector/DefaultCodeCoverageConfig.xml deleted file mode 100644 index 4ead29517a..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/DefaultCodeCoverageConfig.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - .*CPPUnitTestFramework.* - .*vstest.console.* - .*microsoft.intellitrace.* - .*testhost.* - .*datacollector.* - .*microsoft.teamfoundation.testplatform.* - .*microsoft.visualstudio.testplatform.* - .*microsoft.visualstudio.testwindow.* - .*microsoft.visualstudio.mstest.* - .*microsoft.visualstudio.qualitytools.* - .*microsoft.vssdk.testhostadapter.* - .*microsoft.vssdk.testhostframework.* - .*qtagent32.* - .*msvcr.*dll$ - .*msvcp.*dll$ - .*clr.dll$ - .*clr.ni.dll$ - .*clrjit.dll$ - .*clrjit.ni.dll$ - .*mscoree.dll$ - .*mscoreei.dll$ - .*mscoreei.ni.dll$ - .*mscorlib.dll$ - .*mscorlib.ni.dll$ - .*cryptbase.dll$ - .*bcryptPrimitives.dll$ - - - True - True - True - false - - - - ^std::.* - ^ATL::.* - .*::__GetTestMethodInfo.* - .*__CxxPureMSILEntry.* - ^Microsoft::VisualStudio::CppCodeCoverageFramework::.* - ^Microsoft::VisualStudio::CppUnitTestFramework::.* - .*::YOU_CAN_ONLY_DESIGNATE_ONE_.* - ^__.* - .*::__.* - - - - - ^System.Diagnostics.DebuggerHiddenAttribute$ - ^System.Diagnostics.DebuggerNonUserCodeAttribute$ - System.Runtime.CompilerServices.CompilerGeneratedAttribute$ - ^System.CodeDom.Compiler.GeneratedCodeAttribute$ - ^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$ - ^Microsoft.VisualStudio.TestPlatform.TestSDKAutoGeneratedCode.* - - - - - .*\\atlmfc\\.* - .*\\vctools\\.* - .*\\public\\sdk\\.* - .*\\externalapis\\.* - .*\\microsoft sdks\\.* - .*\\vc\\include\\.* - .*\\msclr\\.* - .*\\ucrt\\.* - - - - - - \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/DynamicCoverageDataCollector.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/DynamicCoverageDataCollector.cs deleted file mode 100644 index 6f499016c4..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/DynamicCoverageDataCollector.cs +++ /dev/null @@ -1,259 +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. - -namespace Microsoft.VisualStudio.Coverage -{ - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Xml; - using Interfaces; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; - using Microsoft.VisualStudio.TraceCollector; - using TestPlatform.ObjectModel; - using TraceCollector.Interfaces; - using TraceDataCollector.Resources; - - /// - /// DynamicCoverageDataCollector implements BaseDataCollector for "Code Coverage" . Handles datacollector's SessionStart and SessionsEnd events - /// and provides environment variable required for code coverage profiler. - /// - [DataCollectorTypeUri("datacollector://Microsoft/CodeCoverage/2.0")] - [DataCollectorFriendlyName("Code Coverage")] - public class DynamicCoverageDataCollector : BaseDataCollector - { - private const string VanguardX86ProfilerConfigVariable = "MicrosoftInstrumentationEngine_ConfigPath32_VanguardInstrumentationProfiler"; - private const string VanguardX64ProfilerConfigVariable = "MicrosoftInstrumentationEngine_ConfigPath64_VanguardInstrumentationProfiler"; - - private const string CoreclrProfilerPathVariable32 = "CORECLR_PROFILER_PATH_32"; - private const string CoreclrProfilerPathVariable64 = "CORECLR_PROFILER_PATH_64"; - private const string CoreclrEnableProfilingVariable = "CORECLR_ENABLE_PROFILING"; - private const string CoreclrProfilerVariable = "CORECLR_PROFILER"; - private const string CorProfilerPathVariable32 = "COR_PROFILER_PATH_32"; - private const string CorProfilerPathVariable64 = "COR_PROFILER_PATH_64"; - private const string CorEnableProfilingVariable = "COR_ENABLE_PROFILING"; - private const string CorProfilerVariable = "COR_PROFILER"; - - private const string VanguardProfilerGuid = "{E5F256DC-7959-4DD6-8E4F-C11150AB28E0}"; - private const string VanguardInstrumentationMethodGuid = "{2A1F2A34-8192-44AC-A9D8-4FCC03DCBAA8}"; - private const string ClrInstrumentationEngineProfilerGuid = "{324F817A-7420-4E6D-B3C1-143FBED6D855}"; - - private const string CodeCoverageSessionNameVariable = "CODE_COVERAGE_SESSION_NAME"; - - private const string ClrIeInstrumentationForNetCoreSettingName = "CLRIEInstrumentationNetCore"; - private const string ClrIeInstrumentationForNetFrameworkSettingName = "CLRIEInstrumentationNetFramework"; - private const string ClrIeInstrumentationForNetCoreVariable = "VANGUARD_CLR_IE_INSTRUMENTATION_NETCORE"; - private const string ClrIeInstrumentationForNetFrameworkVariable = "VANGUARD_CLR_IE_INSTRUMENTATION_NETFRAMEWORK"; - - private const string ClrIeLogLevelVariable = @"MicrosoftInstrumentationEngine_LogLevel"; - private const string ClrIeDisableCodeSignatureValidationVariable = @"MicrosoftInstrumentationEngine_DisableCodeSignatureValidation"; - private const string ClrieFileLogPathVariable = @"MicrosoftInstrumentationEngine_FileLogPath"; - - private const string InjectDotnetAdditionalDepsSettingName = "InjectDotnetAdditionalDeps"; - private const string VanguardDotnetAdditionalDepsVariable = "VANGUARD_DOTNET_ADDITIONAL_DEPS"; - - private readonly IEnvironment environment; - private bool useClrIeInstrumentationForNetCore; - private bool useClrIeInstrumentationForNetFramework; - private bool injectDotnetAdditionalDeps; - - /// - /// Data collector implementation - /// - private IDynamicCoverageDataCollectorImpl implementation; - - private IProfilersLocationProvider profilersLocationProvider; - - /// - /// To show warning on non windows. - /// - private bool isWindowsOS; - - public DynamicCoverageDataCollector() - : this( - new ProfilersLocationProvider(), - null, /* DynamicCoverageDataCollectorImpl .ctor has dependency on WinAPIs */ - new PlatformEnvironment()) - { - } - - internal DynamicCoverageDataCollector( - IProfilersLocationProvider vanguardLocationProvider, - IDynamicCoverageDataCollectorImpl dynamicCoverageDataCollectorImpl, - IEnvironment environment) - { - this.profilersLocationProvider = vanguardLocationProvider; - this.environment = environment; - - // Create DynamicCoverageDataCollectorImpl .ctor only when running on windows, because it has dependency on WinAPIs. - if (dynamicCoverageDataCollectorImpl == null) - { - this.isWindowsOS = this.environment.OperatingSystem.Equals(PlatformOperatingSystem.Windows); - if (this.isWindowsOS) - { - this.implementation = new DynamicCoverageDataCollectorImpl(); - } - } - else - { - this.isWindowsOS = true; - this.implementation = dynamicCoverageDataCollectorImpl; - } - } - - protected override void OnInitialize(XmlElement configurationElement) - { - if (this.isWindowsOS == false) - { - EqtTrace.Warning($"DynamicCoverageDataCollector.OnInitialize: Code coverage not supported for operating system: {this.environment.OperatingSystem}"); - - this.Logger.LogWarning( - this.AgentContext.SessionDataCollectionContext, - string.Format(CultureInfo.CurrentUICulture, Resources.CodeCoverageOnlySupportsWindows)); - - return; - } - - try - { - this.useClrIeInstrumentationForNetCore = IsClrInstrumentationEnabled(configurationElement, ClrIeInstrumentationForNetCoreSettingName, ClrIeInstrumentationForNetCoreVariable); - this.useClrIeInstrumentationForNetFramework = IsClrInstrumentationEnabled(configurationElement, ClrIeInstrumentationForNetFrameworkSettingName, ClrIeInstrumentationForNetFrameworkVariable); - this.injectDotnetAdditionalDeps = GetConfigurationValue(configurationElement, InjectDotnetAdditionalDepsSettingName) ?? true; - - this.implementation.Initialize(configurationElement, this.DataSink, this.Logger); - this.Events.SessionStart += this.SessionStart; - this.Events.SessionEnd += this.SessionEnd; - } - catch (Exception ex) - { - EqtTrace.Error("DynamicCoverageDataCollector.OnInitialize: Failed to initialize code coverage datacollector with exception: {0}", ex); - this.Logger.LogError( - this.AgentContext.SessionDataCollectionContext, - string.Format(CultureInfo.CurrentUICulture, Resources.FailedToInitializeCodeCoverageDataCollector, ex)); - throw; - } - } - - /// - /// Dispose. - /// - /// The disposing - protected override void Dispose(bool disposing) - { - this.Events.SessionStart -= this.SessionStart; - this.Events.SessionEnd -= this.SessionEnd; - this.implementation?.Dispose(); - base.Dispose(disposing); - } - - /// - /// The GetEnvironmentVariables - /// - /// Returns EnvironmentVariables required for code coverage profiler. - protected override IEnumerable> GetEnvironmentVariables() - { - if (this.isWindowsOS == false) - { - return Enumerable.Empty>(); - } - - var envVaribles = new List> - { - new KeyValuePair(CoreclrEnableProfilingVariable, "1"), - new KeyValuePair(CoreclrProfilerPathVariable32, this.useClrIeInstrumentationForNetCore ? this.profilersLocationProvider.GetClrInstrumentationEngineX86Path() : this.profilersLocationProvider.GetVanguardProfilerX86Path()), - new KeyValuePair(CoreclrProfilerPathVariable64, this.useClrIeInstrumentationForNetCore ? this.profilersLocationProvider.GetClrInstrumentationEngineX64Path() : this.profilersLocationProvider.GetVanguardProfilerX64Path()), - new KeyValuePair(CoreclrProfilerVariable, this.useClrIeInstrumentationForNetCore ? ClrInstrumentationEngineProfilerGuid : VanguardProfilerGuid), - new KeyValuePair(CodeCoverageSessionNameVariable, this.implementation.GetSessionName()), - new KeyValuePair(CorEnableProfilingVariable, "1"), - new KeyValuePair(CorProfilerPathVariable32, this.useClrIeInstrumentationForNetFramework ? this.profilersLocationProvider.GetClrInstrumentationEngineX86Path() : this.profilersLocationProvider.GetVanguardProfilerX86Path()), - new KeyValuePair(CorProfilerPathVariable64, this.useClrIeInstrumentationForNetFramework ? this.profilersLocationProvider.GetClrInstrumentationEngineX64Path() : this.profilersLocationProvider.GetVanguardProfilerX64Path()), - new KeyValuePair(CorProfilerVariable, this.useClrIeInstrumentationForNetFramework ? ClrInstrumentationEngineProfilerGuid : VanguardProfilerGuid), - new KeyValuePair(VanguardX86ProfilerConfigVariable, this.profilersLocationProvider.GetVanguardProfilerConfigX86Path()), - new KeyValuePair(VanguardX64ProfilerConfigVariable, this.profilersLocationProvider.GetVanguardProfilerConfigX64Path()), - }; - - if (this.useClrIeInstrumentationForNetCore || this.useClrIeInstrumentationForNetFramework) - { - envVaribles.Add(new KeyValuePair(ClrIeLogLevelVariable, "Errors")); - envVaribles.Add(new KeyValuePair($"{ClrIeLogLevelVariable}_{VanguardInstrumentationMethodGuid}", "Errors")); - envVaribles.Add(new KeyValuePair(ClrIeDisableCodeSignatureValidationVariable, "1")); - envVaribles.Add(new KeyValuePair(ClrieFileLogPathVariable, Path.Combine(Path.GetTempPath(), this.implementation.GetSessionName(), Guid.NewGuid() + ".log"))); - } - - if (this.injectDotnetAdditionalDeps && !string.IsNullOrEmpty(this.implementation.CodeCoverageDepsJsonFilePath)) - { - envVaribles.Add(new KeyValuePair(VanguardDotnetAdditionalDepsVariable, this.implementation.CodeCoverageDepsJsonFilePath)); - } - - if (EqtTrace.IsInfoEnabled) - { - EqtTrace.Info("DynamicCoverageDataCollector.GetEnvironmentVariables: Returning following environment variables: {0}", string.Join(",", envVaribles)); - } - - return envVaribles.AsReadOnly(); - } - - /// - /// Check if CLR Instrumentation Engine Instrumentation is enabled - /// - /// Data collector configuration - /// Configuration setting name - /// Environment variable name - /// If CLR IE should be enabled - private static bool IsClrInstrumentationEnabled(XmlElement configurationElement, string configurationSettingName, string environmentVariableName) - { - var clrInstrumentationEnabledByConfiguration = GetConfigurationValue(configurationElement, configurationSettingName); - - if (clrInstrumentationEnabledByConfiguration == true) - { - return true; - } - - var environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName); - if (string.IsNullOrEmpty(environmentVariableValue)) - { - return false; - } - - return int.TryParse(environmentVariableValue, out var environmentVariableIntValue) && environmentVariableIntValue > 0; - } - - /// - /// Check flag in configuration - /// - /// Configuration - /// Configuration setting name - /// Flag value in configuration. Null if not present. - private static bool? GetConfigurationValue(XmlElement configurationElement, string configurationSettingName) - { - if (bool.TryParse(configurationElement?[configurationSettingName]?.InnerText, out var settingValue)) - { - return settingValue; - } - - return null; - } - - /// - /// On session end - /// - /// Sender - /// Event arguments - private void SessionEnd(object sender, SessionEndEventArgs e) - { - this.implementation.SessionEnd(sender, e); - } - - /// - /// On session start - /// - /// Sender - /// Event arguments - private void SessionStart(object sender, SessionStartEventArgs e) - { - this.implementation.SessionStart(sender, e); - } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/DynamicCoverageDataCollectorImpl.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/DynamicCoverageDataCollectorImpl.cs deleted file mode 100644 index 5803d0a954..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/DynamicCoverageDataCollectorImpl.cs +++ /dev/null @@ -1,392 +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. - -namespace Microsoft.VisualStudio.Coverage -{ - using System; - using System.ComponentModel; - using System.Globalization; - using System.IO; - using System.Reflection; - using System.Xml; - using Interfaces; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; - using Microsoft.VisualStudio.TestPlatform.Utilities; - using TestPlatform.ObjectModel; - using TraceCollector; - using TraceCollector.Interfaces; - using TraceDataCollector.Resources; - using IDataCollectionSink = TraceCollector.IDataCollectionSink; - - /// - /// Create config file and output directory required for vanguard process and manages life cycle of vanguard process. - /// - internal class DynamicCoverageDataCollectorImpl : IDynamicCoverageDataCollectorImpl - { - /// - /// Name of elements under which all the config details required for vanguard process. - /// - private const string ConfigCodeCoverageElementName = "CodeCoverage"; - - /// - /// File name which contains config for vanguard process. - /// - private const string VanguardConfigFileName = "CodeCoverage.config"; - - /// - /// File name of deps.json file with reference to Microsoft.VisualStudio.CodeCoverage.Shim.dll. - /// - private const string CodeCoverageDepsJsonFileName = "CodeCoverage.deps.json"; - - /// - /// Name of element for custom coverage filename. - /// - private const string CoverageFileSettingName = "CoverageFileName"; - - private const string CodeCoverageDepsJsonTemplate = @" -{{ - ""runtimeTarget"": {{ - ""name"": ""codecoverage"", - ""signature"": """" - }}, - ""targets"": {{ - ""codecoverage"": {{ - ""Microsoft.VisualStudio.CodeCoverage.Shim/15.0.0.0"": {{ - ""runtime"": {{ - ""{0}"": {{ }} - }} - }} - }} - }}, - ""libraries"": {{ - ""Microsoft.VisualStudio.CodeCoverage.Shim/15.0.0.0"": {{ - ""type"": ""reference"", - ""serviceable"": false, - ""sha512"": """" - }} - }} -}} -"; - - /// - /// Directory helper - /// - private readonly IDirectoryHelper directoryHelper; - - /// - /// Profilers location provider - /// - private readonly IProfilersLocationProvider profilersLocationProvider; - - /// - /// File helper - /// - private readonly IFileHelper fileHelper; - - /// - /// Coverage file name - /// - private string coverageFileName; - - /// - /// Logger - /// - private IDataCollectionLogger logger; - - /// - /// Data sink - /// - private TraceCollector.IDataCollectionSink dataSink; - - /// - /// Folder to store temporary files - /// - private string sessionDirectory; - - private string coverageFilePath; - - public DynamicCoverageDataCollectorImpl() - : this(new Vanguard(), new DirectoryHelper(), new FileHelper(), new ProfilersLocationProvider()) - { - } - - internal DynamicCoverageDataCollectorImpl(IVanguard vanguard, IDirectoryHelper directoryHelper, IFileHelper fileHelper, IProfilersLocationProvider profilersLocationProvider) - { - this.Vanguard = vanguard; - this.directoryHelper = directoryHelper; - this.fileHelper = fileHelper; - this.profilersLocationProvider = profilersLocationProvider; - } - - /// - /// Gets path to deps.json file with reference to Microsoft.VisualStudio.CodeCoverage.Shim.dll. - /// - public string CodeCoverageDepsJsonFilePath { get; private set; } - - /// - /// Gets or sets session name - /// - private string SessionName { get; set; } - - /// - /// Gets or sets vanguard instance - /// - private IVanguard Vanguard { get; set; } - - public string GetSessionName() - { - return this.SessionName; - } - - /// - /// Initialize - /// - /// Configuration element - /// Data sink - /// Logger - public virtual void Initialize( - XmlElement configurationElement, - IDataCollectionSink dataSink, - IDataCollectionLogger logger) - { - var defaultConfigurationElement = DynamicCoverageDataCollectorImpl.GetDefaultConfiguration(); - - try - { - // WARNING: Do NOT remove this function call !!! - // - // Due to a dependency we took on Microsoft.TestPlatform.Utilities.dll, an - // exception may be thrown if we cannot resolve CodeCoverageRunSettingsProcessor. - // If such an exception is thrown we cannot catch it in this try-catch block - // because all method dependencies must be resolved before the method call, thus - // we introduced an additional layer of indirection. - configurationElement = this.AddDefaultExclusions(configurationElement, defaultConfigurationElement); - } - catch (Exception ex) - { - EqtTrace.Warning( - string.Format( - CultureInfo.CurrentCulture, - string.Join( - " ", - "DynamicCoverageDataCollectorImpl.Initialize: Exception encountered while processing the configuration element.", - "Keeping the configuration element unaltered. More info about the exception: {0}"), - ex.Message)); - } - - EqtTrace.Info("DynamicCoverageDataCollectorImpl.Initialize: Initialize configuration. "); - if (string.IsNullOrEmpty(configurationElement?.InnerXml)) - { - configurationElement = defaultConfigurationElement; - } - - this.logger = logger; - this.dataSink = dataSink; - - this.dataSink.SendFileCompleted += this.OnSendFileCompletedEvent; - - this.SessionName = Guid.NewGuid().ToString(); - - this.sessionDirectory = Path.Combine(Path.GetTempPath(), this.SessionName); - this.directoryHelper.CreateDirectory(this.sessionDirectory); - - this.SetCoverageFileName(configurationElement); - - this.PrepareVanguardProcess(configurationElement); - } - - /// - /// Cleanup temp folder - /// - public virtual void Dispose() - { - if (this.Vanguard != null) - { - this.Vanguard.Stop(); - this.Vanguard.Dispose(); - } - - if (this.dataSink != null) - { - this.dataSink.SendFileCompleted -= this.OnSendFileCompletedEvent; - } - - this.CleanupDirectory(); - } - - /// - /// Session start - /// - /// Sender - /// Event arguments - public void SessionStart(object sender, SessionStartEventArgs e) - { - this.StartVanguard(e.Context); - } - - /// - /// Session end - /// - /// Sender - /// Event arguments - public void SessionEnd(object sender, SessionEndEventArgs e) - { - this.StopVanguard(e.Context); - } - - /// - /// Start vanguard - /// - /// Context - protected void StartVanguard(DataCollectionContext context) - { - if (this.Vanguard != null) - { - string outputCoverageFolder = Path.Combine(this.sessionDirectory, Guid.NewGuid().ToString()); - this.CreateDirectory(context, outputCoverageFolder); - - this.coverageFilePath = Path.Combine(outputCoverageFolder, this.coverageFileName); - try - { - this.Vanguard.Start(this.coverageFilePath, context); - } - catch (Exception ex) - { - EqtTrace.Error( - "DynamicCoverageDataCollectorImpl.StartVanguard: Failed to start Vanguard for datacollection context sessionID: {0}, with exception: {1}", - context.SessionId, - ex); - this.logger.LogError(context, ex); - throw; - } - } - } - - /// - /// Stop vanguard - /// - /// Context - protected void StopVanguard(DataCollectionContext context) - { - EqtTrace.Info("DynamicCoverageDataCollectorImpl.StopVanguard: Calling Stop Vanguard. datacollection context sessionID: {0}", context.SessionId); - if (this.Vanguard != null) - { - this.Vanguard.Stop(); - - if (this.fileHelper.Exists(this.coverageFilePath)) - { - this.dataSink.SendFileAsync(context, this.coverageFilePath, false); - } - - this.Vanguard = null; - } - } - - protected void OnSendFileCompletedEvent(object sender, AsyncCompletedEventArgs e) - { - this.CleanupDirectory(); - } - - /// - /// Generate the file name for coverage file. - /// - /// Returns code coverage file name. - private static string GenerateCoverageFileName() - { - string GetUserName() - { - return Environment.GetEnvironmentVariable("USERNAME") ?? Environment.GetEnvironmentVariable("USER"); - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0}_{1}_{2}.coverage", - GetUserName(), - Environment.MachineName, - DateTime.Now.ToString("yyyy-MM-dd.HH_mm_ss", CultureInfo.InvariantCulture)); - } - - private static XmlElement GetDefaultConfiguration() - { - // Add default configuration specific to CodeCoverage. https://msdn.microsoft.com/en-us/library/jj635153.aspx - var doc = new XmlDocument(); - Assembly a = typeof(DynamicCoverageDataCollectorImpl).GetTypeInfo().Assembly; - using (Stream s = a.GetManifestResourceStream( - "Microsoft.VisualStudio.TraceDataCollector.VanguardCollector.DefaultCodeCoverageConfig.xml")) - { - doc.Load(s); - } - - return doc.DocumentElement; - } - - private void SetCoverageFileName(XmlElement configurationElement) - { - XmlElement coverageFileNameElement = configurationElement[CoverageFileSettingName]; - this.coverageFileName = coverageFileNameElement != null - ? coverageFileNameElement.InnerText - : GenerateCoverageFileName(); - } - - private void PrepareVanguardProcess(XmlElement configurationElement) - { - EqtTrace.Info("DynamicCoverageDataCollectorImpl.PrepareVanguardProcess: Preparing Vanguard process."); - - XmlElement config = configurationElement[ConfigCodeCoverageElementName] - ?? DynamicCoverageDataCollectorImpl.GetDefaultConfiguration()[ConfigCodeCoverageElementName]; - - string configurationFileName = Path.Combine(this.sessionDirectory, VanguardConfigFileName); - this.fileHelper.WriteAllText(configurationFileName, config.OuterXml); - - this.CodeCoverageDepsJsonFilePath = Path.Combine(this.sessionDirectory, CodeCoverageDepsJsonFileName); - var codeCoverageDepsJsonContent = this.profilersLocationProvider.GetCodeCoverageShimPath()?.Replace(@"\", "/"); - this.fileHelper.WriteAllText(this.CodeCoverageDepsJsonFilePath, string.Format(CodeCoverageDepsJsonTemplate, codeCoverageDepsJsonContent)); - - EqtTrace.Info("DynamicCoverageDataCollectorImpl.PrepareVanguardProcess: Initializing with config: {0}.", config.OuterXml); - this.Vanguard.Initialize(this.SessionName, configurationFileName, this.logger); - } - - private void CleanupDirectory() - { - try - { - if (this.directoryHelper.Exists(this.sessionDirectory)) - { - this.directoryHelper.Delete(this.sessionDirectory, true); - } - } - catch (Exception ex) - { - EqtTrace.Warning("DynamicCoverageDataCollectorImpl.CleanupDirectory:Failed to delete directory: {0}, with exception: {1}", this.sessionDirectory, ex); - } - } - - private void CreateDirectory(DataCollectionContext context, string path) - { - try - { - this.directoryHelper.CreateDirectory(path); - } - catch (Exception ex) - { - EqtTrace.Error("DynamicCoverageDataCollectorImpl.CreateDirectory:Failed to create directory: {0}, with exception: {1}", path, ex); - this.logger.LogError( - context, - string.Format(CultureInfo.CurrentUICulture, Resources.FailedToCreateDirectory, path, ex)); - throw; - } - } - - /// - /// Adding default exclusions to the configuration element. - /// - /// The configuration element. - /// The default configuration element. - /// The original configuration element with additional default exclusions. - private XmlElement AddDefaultExclusions(XmlElement configurationElement, XmlElement defaultConfigurationElement) - { - var processor = new CodeCoverageRunSettingsProcessor(defaultConfigurationElement); - return (XmlElement)processor.Process(configurationElement); - } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IDynamicCoverageDataCollectorImpl.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IDynamicCoverageDataCollectorImpl.cs deleted file mode 100644 index c87ff56b2a..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IDynamicCoverageDataCollectorImpl.cs +++ /dev/null @@ -1,30 +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. - -namespace Microsoft.VisualStudio.Coverage.Interfaces -{ - using System; - using System.Xml; - using TestPlatform.ObjectModel.DataCollection; - using TraceCollector; - using IDataCollectionSink = TraceCollector.IDataCollectionSink; - - /// - /// The IDynamicCoverageDataCollectorImpl interface. - /// - internal interface IDynamicCoverageDataCollectorImpl : IDisposable - { - string CodeCoverageDepsJsonFilePath { get; } - - string GetSessionName(); - - void Initialize( - XmlElement configurationElement, - IDataCollectionSink dataSink, - IDataCollectionLogger logger); - - void SessionEnd(object sender, SessionEndEventArgs sessionEndEventArgs); - - void SessionStart(object sender, SessionStartEventArgs sessionStartEventArgs); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IProfilersLocationProvider.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IProfilersLocationProvider.cs deleted file mode 100644 index 6ca0fb672f..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IProfilersLocationProvider.cs +++ /dev/null @@ -1,59 +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. - -namespace Microsoft.VisualStudio.Coverage.Interfaces -{ - /// - /// Interface to provide vanguard and CLR IE directory and path. - /// - internal interface IProfilersLocationProvider - { - /// - /// Get path to vanguard exe - /// - /// Vanguard path - string GetVanguardPath(); - - /// - /// Get path to x86 vanguard profiler - /// - /// Vanguard x86 profiler path - string GetVanguardProfilerX86Path(); - - /// - /// Get path to x64 vanguard profiler config - /// - /// Vanguard x64 profiler config path - string GetVanguardProfilerConfigX64Path(); - - /// - /// Get path to x86 vanguard profiler config - /// - /// Vanguard x86 profiler config path - string GetVanguardProfilerConfigX86Path(); - - /// - /// Get path to x64 vanguard profiler - /// - /// Vanguard x64 profiler path - string GetVanguardProfilerX64Path(); - - /// - /// Get path to x86 CLR Instrumentation Engine - /// - /// x86 CLR IE Path - string GetClrInstrumentationEngineX86Path(); - - /// - /// Get path to x64 CLR Instrumentation Engine - /// - /// x64 CLR IE Path - string GetClrInstrumentationEngineX64Path(); - - /// - /// Get path to Microsoft.VisualStudio.CodeCoverage.Shim library - /// - /// Path to Microsoft.VisualStudio.CodeCoverage.Shim library - string GetCodeCoverageShimPath(); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IVanguard.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IVanguard.cs deleted file mode 100644 index 3cf682e22b..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IVanguard.cs +++ /dev/null @@ -1,38 +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. - -namespace Microsoft.VisualStudio.Coverage.Interfaces -{ - using System; - using TestPlatform.ObjectModel.DataCollection; - using TraceCollector; - - /// - /// The IVanguard interface. - /// - internal interface IVanguard : IDisposable - { - /// - /// Initialize Vanguard. - /// - /// Session name - /// Configuration file name - /// Data collection logger. - void Initialize( - string sessionName, - string configurationFileName, - IDataCollectionLogger logger); - - /// - /// Start a vanguard logger. - /// - /// Output file name - /// Data collection context. - void Start(string outputName, DataCollectionContext context); - - /// - /// Stop vanguard logger. - /// - void Stop(); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IVanguardCommandBuilder.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IVanguardCommandBuilder.cs deleted file mode 100644 index aafe00f8c5..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/IVanguardCommandBuilder.cs +++ /dev/null @@ -1,25 +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. - -namespace Microsoft.VisualStudio.Coverage.Interfaces -{ - /// - /// The IVanguardCommandBuilder interface. - /// - internal interface IVanguardCommandBuilder - { - /// - /// Generate a vanguardCommand line string, given some parameters - /// - /// VanguardCommand to execute - /// Session name - /// Output file name (for collect vanguardCommand) - /// Configuration file name - /// VanguardCommand line string - string GenerateCommandLine( - VanguardCommand vanguardCommand, - string sessionName, - string outputName, - string configurationFileName); - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/VanguardCommand.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/VanguardCommand.cs deleted file mode 100644 index b31322a807..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/Interfaces/VanguardCommand.cs +++ /dev/null @@ -1,21 +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. - -namespace Microsoft.VisualStudio.Coverage.Interfaces -{ - /// - /// Commands for vanguard process. - /// - public enum VanguardCommand - { - /// - /// Start the collecting code coverage for given session. - /// - Collect, - - /// - /// Stop the collecting code coverage for given session. - /// - Shutdown - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/ProfilersLocationProvider.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/ProfilersLocationProvider.cs deleted file mode 100644 index ce6230879a..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/ProfilersLocationProvider.cs +++ /dev/null @@ -1,108 +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. - -namespace Microsoft.VisualStudio.TraceCollector -{ - using System; - using System.Globalization; - using System.IO; - using System.Reflection; - using Coverage; - using Coverage.Interfaces; - using TraceDataCollector.Resources; - - internal class ProfilersLocationProvider : IProfilersLocationProvider - { - private const string ClrIeX86InstallDirVariable = "CLRIEX86InstallDir"; - private const string ClrIeX64InstallDirVariable = "CLRIEX64InstallDir"; - private const string ClrIeX86FileName = "MicrosoftInstrumentationEngine_x86.dll"; - private const string ClrIeX64FileName = "MicrosoftInstrumentationEngine_x64.dll"; - - private const string VanguardX86ProfilerPath = @"covrun32.dll"; - private const string VanguardX64ProfilerPath = @"amd64\covrun64.dll"; - private const string VanguardX86ProfilerConfigPath = @"VanguardInstrumentationProfiler_x86.config"; - private const string VanguardX64ProfilerConfigPath = @"amd64\VanguardInstrumentationProfiler_x64.config"; - private const string VanguardShimPath = @"coreclr\Microsoft.VisualStudio.CodeCoverage.Shim.dll"; - - /// - /// Vanguard executable name - /// - private const string VanguardExeName = @"CodeCoverage.exe"; - - /// - public string GetVanguardPath() - { - var vanguardPath = Path.Combine(this.GetVanguardDirectory(), VanguardExeName); - if (!File.Exists(vanguardPath)) - { - throw new VanguardException(string.Format(CultureInfo.CurrentUICulture, Resources.VanguardNotFound, vanguardPath)); - } - - return vanguardPath; - } - - /// - public string GetVanguardProfilerX86Path() - { - return Path.Combine(this.GetVanguardDirectory(), VanguardX86ProfilerPath); - } - - /// - public string GetVanguardProfilerX64Path() - { - return Path.Combine(this.GetVanguardDirectory(), VanguardX64ProfilerPath); - } - - /// - public string GetVanguardProfilerConfigX86Path() - { - return Path.Combine(this.GetVanguardDirectory(), VanguardX86ProfilerConfigPath); - } - - /// - public string GetVanguardProfilerConfigX64Path() - { - return Path.Combine(this.GetVanguardDirectory(), VanguardX64ProfilerConfigPath); - } - - /// - public string GetClrInstrumentationEngineX86Path() - { - return this.GetClrInstrumentationEnginePath("x86", ClrIeX86FileName, ClrIeX86InstallDirVariable); - } - - /// - public string GetClrInstrumentationEngineX64Path() - { - return this.GetClrInstrumentationEnginePath("x64", ClrIeX64FileName, ClrIeX64InstallDirVariable); - } - - /// - public string GetCodeCoverageShimPath() - { - return Path.Combine(this.GetVanguardDirectory(), VanguardShimPath); - } - - private string GetClrInstrumentationEnginePath(string arch, string fileName, string environmentVariableName) - { - var installationPath = Environment.GetEnvironmentVariable(environmentVariableName); - - if (!string.IsNullOrEmpty(installationPath)) - { - return Path.Combine(installationPath, fileName); - } - - return Path.Combine(this.GetCurrentAssemblyLocation(), "InstrumentationEngine", arch, fileName); - } - - private string GetVanguardDirectory() - { - return Path.Combine(this.GetCurrentAssemblyLocation(), "CodeCoverage"); - } - - private string GetCurrentAssemblyLocation() - { - return Path.GetDirectoryName(typeof(ProfilersLocationProvider).GetTypeInfo().Assembly.Location); - } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/Vanguard.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/Vanguard.cs deleted file mode 100644 index 6e1e84cc84..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/Vanguard.cs +++ /dev/null @@ -1,373 +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. - -namespace Microsoft.VisualStudio.Coverage -{ - using System; - using System.Diagnostics; - using System.Globalization; - using System.IO; - using System.Runtime.InteropServices; - using System.Threading; - using Interfaces; - using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; - using Microsoft.VisualStudio.TraceCollector; - using TestPlatform.ObjectModel; - using TraceCollector.Interfaces; - using TraceDataCollector.Resources; - - /// - /// A managed wrapper for Vanguard - /// - internal class Vanguard : IVanguard - { - /// - /// Return value of WaitForSingleObject, which means the object is signaled. - /// - private const uint WaitObject0 = 0x00000000; - - /// - /// Time limit for vanguard process exit event - /// - private const int ProcessExitWaitLimit = 60000; - - /// - /// Prefix for creating event in global namespace - /// - private const string GlobalEventNamePrefix = "Global\\"; - - /// - /// Stop() will use this event to check whether the stop vanguard command - /// successful stop the collect command codecoverage.exe. - /// - private ManualResetEvent vanguardProcessExitEvent; - - /// - /// To monitor vanguard collect command CodeCoverage.exe process. - /// - private Process vanguardProcess; - - /// - /// Session name of the vanguard logger. - /// - private string sessionName; - - /// - /// Vanguard configuration file name. - /// - private string configurationFileName; - - /// - /// Vanguard output file name. - /// - private string outputName; - - /// - /// Helper object to manage child process lifetimes - /// - private IProcessJobObject processJobObject; - - /// - /// Data collection logger - /// - private IDataCollectionLogger logger; - - /// - /// Data collection context - /// - private DataCollectionContext context; - - private IProfilersLocationProvider vanguardLocationProvider; - - private IVanguardCommandBuilder vanguardCommandBuilder; - - public Vanguard() - : this(new ProfilersLocationProvider(), new VanguardCommandBuilder(), new ProcessJobObject()) - { - } - - internal Vanguard( - IProfilersLocationProvider vanguardLocationProvider, - IVanguardCommandBuilder commandBuilder, - IProcessJobObject processJobObject) - { - this.vanguardLocationProvider = vanguardLocationProvider; - this.vanguardCommandBuilder = commandBuilder; - this.processJobObject = processJobObject; - } - - /// - /// Gets a value indicating whether vanguard is running - /// - private bool IsRunning - { - get { return this.vanguardProcess != null && !this.vanguardProcess.HasExited; } - } - - /// - public void Initialize( - string sessionName, - string configurationFileName, - IDataCollectionLogger logger) - { - EqtTrace.Info("Vanguard.Initialize: Session name: {0}, config filename: {1}", sessionName, configurationFileName); - - this.sessionName = sessionName; - this.configurationFileName = configurationFileName; - this.logger = logger; - } - - /// - public virtual void Start(string outputName, DataCollectionContext context) - { - EqtTrace.Info("Vanguard.Start: Starting CodeCoverage.exe for output file: {0} datacollection session id: {1}", outputName, context.SessionId); - - this.vanguardProcessExitEvent = new ManualResetEvent(false); - this.outputName = outputName; - this.context = context; - var collectCommand = this.vanguardCommandBuilder.GenerateCommandLine( - VanguardCommand.Collect, - this.sessionName, - this.outputName, - this.configurationFileName); - - this.vanguardProcess = this.StartVanguardProcess(collectCommand, false, true); - this.WaitForRunningEvent(); - } - - /// - public virtual void Stop() - { - EqtTrace.Info("Vanguard.Stop: Stopping Vanguard."); - if (this.IsRunning) - { - var shutdownCommand = this.vanguardCommandBuilder.GenerateCommandLine( - VanguardCommand.Shutdown, - this.sessionName, - null, - null); - this.StartVanguardProcess(shutdownCommand, true); - - if (this.vanguardProcessExitEvent.WaitOne(ProcessExitWaitLimit) == false) - { - EqtTrace.Warning("Vanguard.Stop: Vanguard process not exited in {0} ms", ProcessExitWaitLimit); - } - - if (this.processJobObject != null) - { - this.processJobObject.Dispose(); - this.processJobObject = null; - } - } - } - - /// - public virtual void Dispose() - { - EqtTrace.Info("Vanguard.Dispose: Disposing vanguard process."); - if (this.vanguardProcess != null) - { - this.vanguardProcess.Dispose(); - this.vanguardProcess = null; - } - } - - /// - /// CreateEvent API - /// - /// A point to SECURITY_ATTRIBUTES structure - /// Whether the event needs manual reset - /// Initial state of the event - /// Name of the event - /// Event handle - [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - private static extern IntPtr CreateEvent( - IntPtr lpEventAttributes, - bool bManualReset, - bool bInitialState, - string lpName); - - /// - /// Waits until one or all of the specified objects are in the signaled state or the time-out interval elapses. - /// - /// Number of handles - /// Object handles - /// Whether to wait all handles - /// Time-out interval - /// Wait result - [DllImport("kernel32.dll")] - private static extern uint WaitForMultipleObjects( - uint nCount, - IntPtr[] lpHandles, - bool bWaitAll, - uint dwMilliseconds); - - /// - /// Close a handle - /// - /// Object handle - /// True if succeeded - [DllImport("kernel32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool CloseHandle(IntPtr hObject); - - private static int GetProcessId(Process process) - { - var id = 0; - try - { - id = process.Id; - } - catch (Exception ex) - { - EqtTrace.Info("Vanguard.GetProcessId: Fail to get process id with exception: {0}", ex); - } - - return id; - } - - /// - /// Start a vanguard process - /// - /// VanguardCommand line options - /// Whether to wait until the process exits - /// The standardErrorAsynchronousCall. - /// Process instance of vanguard - private Process StartVanguardProcess( - string commandLine, - bool wait, - bool standardErrorAsynchronousCall = false) - { - string vanguardPath = this.vanguardLocationProvider.GetVanguardPath(); - EqtTrace.Info( - "Vanguard.StartVanguardProcess: Starting {0} with command line: {1}, wait for exit:{2}, Read stderr: {3}", - vanguardPath, - commandLine, - wait, - standardErrorAsynchronousCall); - ProcessStartInfo info = new ProcessStartInfo(vanguardPath, commandLine); - info.WorkingDirectory = Directory.GetCurrentDirectory(); - info.UseShellExecute = false; - info.CreateNoWindow = true; - info.RedirectStandardError = true; - - Process process = new Process(); - process.StartInfo = info; - process.EnableRaisingEvents = true; - - if (standardErrorAsynchronousCall) - { - process.ErrorDataReceived += this.LoggerProcessErrorDataReceived; - process.Exited += this.LoggerProcessExited; - } - - process.Start(); - - if (standardErrorAsynchronousCall) - { - process.BeginErrorReadLine(); - } - - if (wait) - { - process.WaitForExit(); - } - else if (this.processJobObject != null) - { - EqtTrace.Info("Vanguard.StartVanguardProcess: Add Vanguard process to the project object"); - this.processJobObject.AddProcess(process.SafeHandle.DangerousGetHandle()); - } - - EqtTrace.Info( - "Vanguard.StartVanguardProcess: Started Vanguard process id :{0}", - Vanguard.GetProcessId(process)); - - return process; - } - - /// - /// WaitForRunningEvent until vanguard initialization is finished - /// - private void WaitForRunningEvent() - { - EqtTrace.Info("Vanguard.WaitForRunningEvent: Waiting for CodeCoverage.exe initialization."); - IntPtr runningEvent = CreateEvent( - IntPtr.Zero, - true, - false, - GlobalEventNamePrefix + this.sessionName + "_RUNNING"); - var timeout = EnvironmentHelper.GetConnectionTimeout(); - if (runningEvent != IntPtr.Zero) - { - uint waitTimeout = (uint)timeout * 1000; // Time limit for waiting for vanguard running event. - - IntPtr[] handles = new IntPtr[] { runningEvent, this.vanguardProcess.SafeHandle.DangerousGetHandle() }; - uint result = WaitForMultipleObjects((uint)handles.Length, handles, false, waitTimeout); - CloseHandle(runningEvent); - switch (result) - { - case WaitObject0: - EqtTrace.Info("Vanguard.WaitForRunningEvent: Running event received from CodeCoverage.exe."); - return; - case WaitObject0 + 1: - // Process exited, something wrong happened - // we have already set to read messages asynchronously, so calling this.vanguardProcess.StandardError.ReadToEnd() which is synchronous is wrong. - // throw new VanguardException(string.Format(CultureInfo.CurrentCulture, Resources.ErrorLaunchVanguard, this.vanguardProcess.StandardError.ReadToEnd())); - EqtTrace.Error("Vanguard.WaitForRunningEvent: From CodeCoverage.exe failed to receive running event in {0} seconds", timeout); - throw new VanguardException(string.Format(CultureInfo.CurrentUICulture, Resources.NoRunningEventFromVanguard)); - } - } - - // No running event received from code coverage.exe and not exited. Kill the CodeCoverage.exe. - try - { - EqtTrace.Error("Vanguard.WaitForRunningEvent: Fail to create running event. Killing CodeCoverage.exe. "); - this.vanguardProcess.Kill(); - } - catch (Exception ex) - { - EqtTrace.Warning("Vanguard.WaitForRunningEvent: Fail to kill CodeCoverage.exe. process with exception: {0}", ex); - } - - throw new VanguardException(string.Format(CultureInfo.CurrentUICulture, Resources.VanguardConnectionTimeout, timeout, EnvironmentHelper.VstestConnectionTimeout)); - } - - /// - /// Handler for vanguard process exit event - /// - /// The sender. - /// Event args. - private void LoggerProcessExited(object sender, EventArgs e) - { - EqtTrace.Info("Vanguard.LoggerProcessExited: Vanguard process exit callback started."); - if (this.vanguardProcess != null) - { - if (this.vanguardProcess.HasExited == true && this.vanguardProcess.ExitCode != 0) - { - EqtTrace.Warning("Vanguard.LoggerProcessExited: An error occurred in Code Coverage process. Error code = {0}", this.vanguardProcess.ExitCode); - } - - this.vanguardProcess.Exited -= this.LoggerProcessExited; - this.vanguardProcess.ErrorDataReceived -= this.LoggerProcessErrorDataReceived; - - this.vanguardProcessExitEvent.Set(); - } - } - - /// - /// Handler for vanguard process error stream - /// - /// The sender - /// Event args - private void LoggerProcessErrorDataReceived(object sender, DataReceivedEventArgs e) - { - EqtTrace.Warning("Vanguard.LoggerProcessErrorDataReceived: received error data: {0}", e.Data); - - if (this.logger != null && this.context != null && !string.IsNullOrWhiteSpace(e.Data)) - { - this.logger.LogWarning(this.context, e.Data); - } - } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/VanguardCommandBuilder.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/VanguardCommandBuilder.cs deleted file mode 100644 index 562975f88f..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/VanguardCommandBuilder.cs +++ /dev/null @@ -1,47 +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. - -namespace Microsoft.VisualStudio.Coverage -{ - using System.Globalization; - using System.Text; - using Interfaces; - using TestPlatform.ObjectModel; - - /// - /// The VanguardCommandBuilder class. - /// - internal class VanguardCommandBuilder : IVanguardCommandBuilder - { - /// - public string GenerateCommandLine( - VanguardCommand vanguardCommand, - string sessionName, - string outputName, - string configurationFileName) - { - StringBuilder builder = new StringBuilder(); - switch (vanguardCommand) - { - case VanguardCommand.Collect: - builder.AppendFormat( - CultureInfo.InvariantCulture, - "collect /session:{0} /output:\"{1}\"", - sessionName, - outputName); - if (!string.IsNullOrEmpty(configurationFileName)) - { - builder.AppendFormat(CultureInfo.InvariantCulture, " /config:\"{0}\"", configurationFileName); - } - - break; - case VanguardCommand.Shutdown: - builder.AppendFormat(CultureInfo.InvariantCulture, "shutdown /session:{0}", sessionName); - break; - } - - EqtTrace.Info("VanguardCommandBuilder.GenerateCommandLine: Created the vanguardCommand: {0}", builder); - return builder.ToString(); - } - } -} \ No newline at end of file diff --git a/src/DataCollectors/TraceDataCollector/VanguardCollector/VanguardException.cs b/src/DataCollectors/TraceDataCollector/VanguardCollector/VanguardException.cs deleted file mode 100644 index 6e0b0efa09..0000000000 --- a/src/DataCollectors/TraceDataCollector/VanguardCollector/VanguardException.cs +++ /dev/null @@ -1,23 +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. - -namespace Microsoft.VisualStudio.Coverage -{ - using System; - - /// - /// VanguardException class - /// - internal class VanguardException : Exception - { - /// - /// Initializes a new instance of the class. - /// Constructor - /// - /// Error message - internal VanguardException(string message) - : base(message) - { - } - } -} \ No newline at end of file diff --git a/src/package/nuspec/Microsoft.CodeCoverage.nuspec b/src/package/nuspec/Microsoft.CodeCoverage.nuspec index 7028c2f603..9974431155 100644 --- a/src/package/nuspec/Microsoft.CodeCoverage.nuspec +++ b/src/package/nuspec/Microsoft.CodeCoverage.nuspec @@ -19,7 +19,7 @@ - + @@ -51,19 +51,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/package/nuspec/Microsoft.TestPlatform.nuspec b/src/package/nuspec/Microsoft.TestPlatform.nuspec index cf8b50f0d3..4a5168f3f5 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.nuspec @@ -266,7 +266,20 @@ - + + + + + + + + + + + + + + diff --git a/src/package/sign/sign.proj b/src/package/sign/sign.proj index fc155e16ef..ee7aae7ba3 100644 --- a/src/package/sign/sign.proj +++ b/src/package/sign/sign.proj @@ -369,20 +369,6 @@
- - - - - - - - - - - - - - diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/DefaultCodeCoverageConfig.xml b/test/DataCollectors/TraceDataCollector.UnitTests/DefaultCodeCoverageConfig.xml deleted file mode 100644 index 619819d6d3..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/DefaultCodeCoverageConfig.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - .*CPPUnitTestFramework.* - .*vstest.console.* - .*microsoft.intellitrace.* - .*testhost.* - .*datacollector.* - .*microsoft.teamfoundation.testplatform.* - .*microsoft.visualstudio.testplatform.* - .*microsoft.visualstudio.testwindow.* - .*microsoft.visualstudio.mstest.* - .*microsoft.visualstudio.qualitytools.* - .*microsoft.vssdk.testhostadapter.* - .*microsoft.vssdk.testhostframework.* - .*qtagent32.* - .*msvcr.*dll$ - .*msvcp.*dll$ - .*clr.dll$ - .*clr.ni.dll$ - .*clrjit.dll$ - .*clrjit.ni.dll$ - .*mscoree.dll$ - .*mscoreei.dll$ - .*mscoreei.ni.dll$ - .*mscorlib.dll$ - .*mscorlib.ni.dll$ - .*cryptbase.dll$ - .*bcryptPrimitives.dll$ - - - True - True - True - false - - - - ^std::.* - ^ATL::.* - .*::__GetTestMethodInfo.* - .*__CxxPureMSILEntry.* - ^Microsoft::VisualStudio::CppCodeCoverageFramework::.* - ^Microsoft::VisualStudio::CppUnitTestFramework::.* - .*::YOU_CAN_ONLY_DESIGNATE_ONE_.* - ^__.* - .*::__.* - - - - - ^System.Diagnostics.DebuggerHiddenAttribute$ - ^System.Diagnostics.DebuggerNonUserCodeAttribute$ - System.Runtime.CompilerServices.CompilerGeneratedAttribute$ - ^System.CodeDom.Compiler.GeneratedCodeAttribute$ - ^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$ - ^Microsoft.VisualStudio.TestPlatform.TestSDKAutoGeneratedCode.* - - - - - .*\\atlmfc\\.* - .*\\vctools\\.* - .*\\public\\sdk\\.* - .*\\externalapis\\.* - .*\\microsoft sdks\\.* - .*\\vc\\include\\.* - .*\\msclr\\.* - .*\\ucrt\\.* - - - - - diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/DynamicCoverageDataCollectorImplTests.cs b/test/DataCollectors/TraceDataCollector.UnitTests/DynamicCoverageDataCollectorImplTests.cs deleted file mode 100644 index 4b1b3f182f..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/DynamicCoverageDataCollectorImplTests.cs +++ /dev/null @@ -1,489 +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. - -namespace Microsoft.VisualStudio.TraceDataCollector.UnitTests -{ - using System; - using System.Collections.Generic; - using System.ComponentModel; - using System.Globalization; - using System.IO; - using System.Xml; - using Coverage; - using Coverage.Interfaces; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - using Newtonsoft.Json; - using Newtonsoft.Json.Linq; - using TestPlatform.ObjectModel.DataCollection; - using TraceCollector; - using TraceCollector.Interfaces; - - [TestClass] - public class DynamicCoverageDataCollectorImplTests - { - private const string DefaultConfigFileName = "CodeCoverage.config"; - private const string DefaultCoverageFileName = "abc.coverage"; - - private static XmlElement sampleConfigurationElement = - DynamicCoverageDataCollectorImplTests.CreateXmlElement($@" - {DefaultCoverageFileName} - - - "); - - private DynamicCoverageDataCollectorImpl collectorImpl; - private Mock vanguardMock; - private Mock dataCollectionSinkMock; - private Mock dataCollectionLoggerMock; - private Mock directoryHelperMock; - private Mock fileHelperMock; - private Mock profilersLocationProviderMock; - - private string aConfigFileName; - private string atempDirectory; - private string tempSessionDir; - - public DynamicCoverageDataCollectorImplTests() - { - this.vanguardMock = new Mock(); - this.dataCollectionSinkMock = new Mock(); - this.dataCollectionLoggerMock = new Mock(); - this.directoryHelperMock = new Mock(); - this.fileHelperMock = new Mock(); - this.profilersLocationProviderMock = new Mock(); - this.tempSessionDir = null; - this.collectorImpl = new DynamicCoverageDataCollectorImpl(this.vanguardMock.Object, this.directoryHelperMock.Object, this.fileHelperMock.Object, this.profilersLocationProviderMock.Object); - this.SetupForInitialize(); - this.collectorImpl.Initialize(DynamicCoverageDataCollectorImplTests.sampleConfigurationElement, this.dataCollectionSinkMock.Object, this.dataCollectionLoggerMock.Object); - } - - [TestCleanup] - public void Cleanup() - { - if (this.tempSessionDir != null) - { - if (Directory.Exists(this.tempSessionDir)) - { - Directory.Delete(this.tempSessionDir, true); - } - } - } - - #region Initialize Tests - [TestMethod] - public void InitializeShouldCreateDefaultCodeCoverageSettingsIfConfigElementIsNull() - { - this.directoryHelperMock.Setup(d => d.CreateDirectory(It.IsAny())) - .Callback((path) => Directory.CreateDirectory(path)); - - this.fileHelperMock.Setup(f => f.WriteAllText(It.IsAny(), It.IsAny())) - .Callback((path, content) => { File.WriteAllText(path, content); }); - - this.collectorImpl.Initialize(null, this.dataCollectionSinkMock.Object, this.dataCollectionLoggerMock.Object); - - Assert.AreEqual(DynamicCoverageDataCollectorImplTests.DefaultConfigFileName, Path.GetFileName(this.aConfigFileName)); - StringAssert.Contains(this.aConfigFileName, Path.GetTempPath()); - this.CompareWithDefaultConfig(); - } - - [TestMethod] - public void InitializeShouldGenerateCodeCoverageDepsJsonFile() - { - this.directoryHelperMock.Setup(d => d.CreateDirectory(It.IsAny())) - .Callback((path) => Directory.CreateDirectory(path)); - - this.fileHelperMock.Setup(f => f.WriteAllText(It.IsAny(), It.IsAny())) - .Callback((path, content) => { File.WriteAllText(path, content); }); - - this.profilersLocationProviderMock.Setup(lp => lp.GetCodeCoverageShimPath()).Returns(@"C:\aaa\bbb\Microsoft.VisualStudio.CodeCoverage.Shim.dll"); - - this.collectorImpl.Initialize(null, this.dataCollectionSinkMock.Object, this.dataCollectionLoggerMock.Object); - - var obj = JObject.Parse(File.ReadAllText(this.collectorImpl.CodeCoverageDepsJsonFilePath)); - - var expected = @" -{ - ""runtimeTarget"": { - ""name"": ""codecoverage"", - ""signature"": """" - }, - ""targets"": { - ""codecoverage"": { - ""Microsoft.VisualStudio.CodeCoverage.Shim/15.0.0.0"": { - ""runtime"": { - ""C:/aaa/bbb/Microsoft.VisualStudio.CodeCoverage.Shim.dll"": { } - } - } - } - }, - ""libraries"": { - ""Microsoft.VisualStudio.CodeCoverage.Shim/15.0.0.0"": { - ""type"": ""reference"", - ""serviceable"": false, - ""sha512"": """" - } - } -}"; - - Assert.AreEqual(expected.Trim(), File.ReadAllText(this.collectorImpl.CodeCoverageDepsJsonFilePath).Trim()); - } - - [TestMethod] - public void InitializeShouldInitializeVanguardWithRightCoverageSettings() - { - XmlElement configElement = - DynamicCoverageDataCollectorImplTests.CreateXmlElement(@""); - - this.directoryHelperMock.Setup(d => d.CreateDirectory(It.IsAny())) - .Callback((path) => - { - this.tempSessionDir = path; - Directory.CreateDirectory(path); - }); - - this.fileHelperMock.Setup(f => f.WriteAllText(It.IsAny(), It.IsAny())) - .Callback((path, content) => { File.WriteAllText(path, content); }); - - this.collectorImpl.Initialize(configElement, this.dataCollectionSinkMock.Object, this.dataCollectionLoggerMock.Object); - - XmlDocument defaultDocument = new XmlDocument(); - defaultDocument.LoadXml(DynamicCoverageDataCollectorImplTests.GetDefaultCodeCoverageConfig()); - - Assert.AreEqual(DynamicCoverageDataCollectorImplTests.DefaultConfigFileName, Path.GetFileName(this.aConfigFileName)); - - XmlDocument currentDocument = new XmlDocument(); - currentDocument.LoadXml(File.ReadAllText(this.aConfigFileName)); - - var codeCoverageNodes = new Tuple(currentDocument.DocumentElement, defaultDocument.DocumentElement); - - this.CompareResults(codeCoverageNodes.Item1, codeCoverageNodes.Item2, "./ModulePaths/Exclude"); - this.CompareResults(codeCoverageNodes.Item1, codeCoverageNodes.Item2, "./Functions/Exclude"); - this.CompareResults(codeCoverageNodes.Item1, codeCoverageNodes.Item2, "./Attributes/Exclude"); - this.CompareResults(codeCoverageNodes.Item1, codeCoverageNodes.Item2, "./Sources/Exclude"); - } - - [TestMethod] - public void InitializeShouldInitializeDefaultConfigIfNoCodeCoverageConfigExists() - { - XmlElement configElement = - DynamicCoverageDataCollectorImplTests.CreateXmlElement($".NETCoreApp,Version=v1.1"); - - this.directoryHelperMock.Setup(d => d.CreateDirectory(It.IsAny())) - .Callback((path) => - { - this.tempSessionDir = path; - Directory.CreateDirectory(path); - }); - - this.fileHelperMock.Setup(f => f.WriteAllText(It.IsAny(), It.IsAny())) - .Callback((path, content) => { File.WriteAllText(path, content); }); - - this.collectorImpl.Initialize(configElement, this.dataCollectionSinkMock.Object, this.dataCollectionLoggerMock.Object); - - this.CompareWithDefaultConfig(); - } - - [TestMethod] - public void InitializeShouldRegisterForSendFileCompleteEvent() - { - this.directoryHelperMock.Setup(d => d.Exists(this.atempDirectory)).Returns(true); - this.dataCollectionSinkMock.Raise(s => s.SendFileCompleted += null, new AsyncCompletedEventArgs(null, false, null)); - this.directoryHelperMock.Verify(d => d.Exists(this.atempDirectory)); - this.directoryHelperMock.Verify(d => d.Delete(this.atempDirectory, true)); - } - - [TestMethod] - public void InitializeShouldCreateTempDirectoryForSession() - { - this.directoryHelperMock.Verify(d => d.CreateDirectory(this.atempDirectory)); - } - - #endregion - - #region Dispose Tests - [TestMethod] - public void DisposeShouldStopVanguard() - { - this.collectorImpl.Dispose(); - this.vanguardMock.Verify(v => v.Stop()); - } - - [TestMethod] - public void DisposeShouldDisposeVanguard() - { - this.collectorImpl.Dispose(); - this.vanguardMock.Verify(v => v.Dispose()); - } - - [TestMethod] - public void DisposeShouldDeleteTempDirectory() - { - this.directoryHelperMock.Setup(d => d.Exists(this.atempDirectory)).Returns(true); - this.collectorImpl.Dispose(); - this.directoryHelperMock.Verify(d => d.Delete(this.atempDirectory, true)); - } - - [TestMethod] - public void DisposeShouldNotDeleteTempDirectoryIfNotExists() - { - this.directoryHelperMock.Setup(d => d.Exists(this.atempDirectory)).Returns(false); - this.collectorImpl.Dispose(); - this.directoryHelperMock.Verify(d => d.Delete(this.atempDirectory, true), Times.Never); - } - - [TestMethod] - public void DisposeShouldUnregisterFileCompleteEvent() - { - this.collectorImpl.Dispose(); - this.dataCollectionSinkMock.Raise(s => s.SendFileCompleted += null, new AsyncCompletedEventArgs(null, false, null)); - this.directoryHelperMock.Verify(d => d.Exists(this.atempDirectory), Times.Once); - } - - #endregion - - #region SessionStart Tests - - [TestMethod] - public void SessionStartShouldCreateDirectoryForCoverageFile() - { - var sessionStartEventArgs = new SessionStartEventArgs(); - var coverageFilePath = string.Empty; - - this.vanguardMock.Setup(v => v.Start(It.IsAny(), It.IsAny())) - .Callback((filePath, dcContext) => - { - coverageFilePath = filePath; - }); - this.collectorImpl.SessionStart(null, sessionStartEventArgs); - - StringAssert.StartsWith(Path.GetDirectoryName(coverageFilePath), this.atempDirectory); - StringAssert.EndsWith(coverageFilePath, DynamicCoverageDataCollectorImplTests.DefaultCoverageFileName); - } - - [TestMethod] - public void SessionStartShouldUseAutoGenrateCoverageFileNameIfNotSpecified() - { - var sessionStartEventArgs = new SessionStartEventArgs(); - var coverageFilePath = string.Empty; - - this.collectorImpl.Initialize(null, this.dataCollectionSinkMock.Object, this.dataCollectionLoggerMock.Object); - this.vanguardMock.Setup(v => v.Start(It.IsAny(), It.IsAny())) - .Callback((filePath, dcContext) => - { - coverageFilePath = filePath; - }); - this.collectorImpl.SessionStart(null, sessionStartEventArgs); - - StringAssert.StartsWith(Path.GetDirectoryName(coverageFilePath), this.atempDirectory); - StringAssert.Contains(coverageFilePath, DynamicCoverageDataCollectorImplTests.GetAutoGenerageCodeCoverageFileNamePrefix()); - } - - [TestMethod] - public void SessionStartShouldLogWarningOnFailToCreateDirectory() - { - var sessionStartEventArgs = new SessionStartEventArgs(); - - var expectedErrorMessage = "Failed to create directory"; - var directoryPath = string.Empty; - - this.directoryHelperMock.Setup(d => d.CreateDirectory(It.IsAny())) - .Callback((d) => { directoryPath = d; }) - .Throws(new Exception(expectedErrorMessage)); - - var actualLoggedMessage = string.Empty; - this.dataCollectionLoggerMock.Setup(l => l.LogError(It.IsAny(), It.IsAny())) - .Callback((c, m) => { actualLoggedMessage = m; }); - - var actualErrorMessage = Assert.ThrowsException(() => this.collectorImpl.SessionStart(null, sessionStartEventArgs)).Message; - - Assert.AreEqual(expectedErrorMessage, actualErrorMessage); - - var expectedLogMessage = string.Format("Failed to create directory: {0} with error:System.Exception: {1}", directoryPath, expectedErrorMessage); - - StringAssert.StartsWith(actualLoggedMessage, expectedLogMessage); - } - - [TestMethod] - public void SessionStartShouldStartVanguard() - { - var sessionStartEventArgs = new SessionStartEventArgs(); - - this.collectorImpl.SessionStart(null, sessionStartEventArgs); - - this.vanguardMock.Verify(v => v.Start(It.IsAny(), It.IsAny())); - } - - [TestMethod] - public void SessionStartShouldLogErrorOnException() - { - var sessionStartEventArgs = new SessionStartEventArgs(); - var exceptionMessage = "Vanguard not found"; - Exception expectedEx = null; - this.vanguardMock.Setup(d => d.Start(It.IsAny(), It.IsAny())) - .Throws(new VanguardException(exceptionMessage)); - this.dataCollectionLoggerMock - .Setup(l => l.LogError(It.IsAny(), It.IsAny())) - .Callback((context, ex) => - { - expectedEx = ex; - }); - var actualEx = Assert.ThrowsException(() => this.collectorImpl.SessionStart(null, sessionStartEventArgs)); - - this.vanguardMock.Verify(v => v.Start(It.IsAny(), It.IsAny())); - Assert.AreEqual(expectedEx, actualEx); - StringAssert.Contains(actualEx.Message, exceptionMessage); - } - - #endregion - - #region SessionStart Tests - - [TestMethod] - public void SessionEndShouldStopVanguard() - { - var sessionEndEventArgs = new SessionEndEventArgs(); - - this.collectorImpl.SessionEnd(null, sessionEndEventArgs); - - this.vanguardMock.Verify(v => v.Stop()); - } - - [TestMethod] - public void SessionEndShouldSendCoverageFile() - { - string tempFile = Path.GetTempFileName(); - var sessionEndEventArgs = new SessionEndEventArgs(); - this.fileHelperMock.Setup(f => f.Exists(It.IsAny())).Returns(true); - this.collectorImpl.SessionEnd(null, sessionEndEventArgs); - - this.dataCollectionSinkMock.Verify(s => s.SendFileAsync(It.IsAny(), It.IsAny(), false)); - } - - #endregion - - internal static XmlElement CreateXmlElement(string xmlString) - { - var doc = new XmlDocument(); - using ( - var xmlReader = XmlReader.Create( - new StringReader(xmlString), - new XmlReaderSettings() { CloseInput = true, DtdProcessing = DtdProcessing.Prohibit })) - { - doc.Load(xmlReader); - } - - return doc.DocumentElement; - } - - #region private methods - - private static string GetAutoGenerageCodeCoverageFileNamePrefix() - { - string GetUserName() - { - return Environment.GetEnvironmentVariable("USERNAME") ?? Environment.GetEnvironmentVariable("USER"); - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0}_{1}", - GetUserName(), - Environment.MachineName); - } - - private static string GetDefaultCodeCoverageConfig() - { - string result = string.Empty; - - using (Stream stream = typeof(DynamicCoverageDataCollectorImplTests).Assembly. - GetManifestResourceStream("Microsoft.VisualStudio.TraceDataCollector.UnitTests.DefaultCodeCoverageConfig.xml")) - { - using (StreamReader sr = new StreamReader(stream)) - { - result = sr.ReadToEnd(); - } - } - - return result; - } - - private void SetupForInitialize() - { - this.vanguardMock.Setup(v => v.Initialize( - It.IsAny(), - It.IsAny(), - It.IsAny())) - .Callback( - (sessionName, configFileName, logger) => - { - this.aConfigFileName = configFileName; - }); - - this.directoryHelperMock.Setup(d => d.CreateDirectory(It.IsAny())).Callback( - (directoryPath) => { this.atempDirectory = directoryPath; }); - } - - private void CompareWithDefaultConfig() - { - Assert.AreEqual( - DynamicCoverageDataCollectorImplTests.GetDefaultCodeCoverageConfig().Replace(" ", string.Empty) - .Replace("\r", string.Empty).Replace("\n", string.Empty), - File.ReadAllText(this.aConfigFileName).Replace(" ", string.Empty).Replace("\r", string.Empty).Replace("\n", string.Empty)); - } - - private XmlNode ExtractNode(XmlNode node, string path) - { - try - { - return node.SelectSingleNode(path); - } - catch - { - } - - return null; - } - - private Tuple ExtractNodes(XmlNode currentSettingsRoot, XmlNode defaultSettingsRoot, string path) - { - var currentNode = this.ExtractNode(currentSettingsRoot, path); - var defaultNode = this.ExtractNode(defaultSettingsRoot, path); - Assert.IsNotNull(currentNode); - Assert.IsNotNull(defaultNode); - - return new Tuple(currentNode, defaultNode); - } - - private void CompareResults(XmlNode currentSettingsRoot, XmlNode defaultSettingsRoot, string path) - { - var nodes = this.ExtractNodes(currentSettingsRoot, defaultSettingsRoot, path); - - Assert.AreEqual(nodes.Item1.ChildNodes.Count, nodes.Item2.ChildNodes.Count); - - var set = new HashSet(); - foreach (XmlNode child in nodes.Item1.ChildNodes) - { - if (!set.Contains(child.OuterXml)) - { - set.Add(child.OuterXml); - } - } - - foreach (XmlNode child in nodes.Item2.ChildNodes) - { - if (!set.Contains(child.OuterXml)) - { - set.Add(child.OuterXml); - continue; - } - - set.Remove(child.OuterXml); - } - - Assert.AreEqual(set.Count, 0); - } - - #endregion - } -} diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/DynamicCoverageDataCollectorTests.cs b/test/DataCollectors/TraceDataCollector.UnitTests/DynamicCoverageDataCollectorTests.cs deleted file mode 100644 index a30769e1d1..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/DynamicCoverageDataCollectorTests.cs +++ /dev/null @@ -1,412 +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. - -namespace Microsoft.VisualStudio.TraceDataCollector.UnitTests -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Xml; - using Coverage; - using Coverage.Interfaces; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - using TestPlatform.ObjectModel.DataCollection; - using TraceCollector; - using TraceCollector.Interfaces; - using IDataCollectionSink = TraceCollector.IDataCollectionSink; - - [TestClass] - public class DynamicCoverageDataCollectorTests - { - private const string DefaultConfig = - ".NETCoreApp,Version=v2.0x64"; - - private const string ConfigWithClrIeEnabledForNetCore = - @" - .NETCoreApp,Version=v2.0 - x64 - true - false - false - "; - - private const string ConfigWithClrIeEnabled = - @" - .NETCoreApp,Version=v2.0 - x64 - true - true - true - "; - - private TestableDynamicCoverageDataCollector collector; - private Mock vanguardLocationProviderMock; - private Mock implMock; - private Mock eventsMock; - private Mock sinkMock; - private Mock loggerMock; - private Mock agentContextMock; - private Mock environmentMock; - - public DynamicCoverageDataCollectorTests() - { - this.vanguardLocationProviderMock = new Mock(); - this.implMock = new Mock(); - this.eventsMock = new Mock(); - this.sinkMock = new Mock(); - this.loggerMock = new Mock(); - this.agentContextMock = new Mock(); - this.environmentMock = new Mock(); - this.collector = new TestableDynamicCoverageDataCollector(this.vanguardLocationProviderMock.Object, this.implMock.Object, this.environmentMock.Object); - - this.vanguardLocationProviderMock.Setup(u => u.GetVanguardProfilerX86Path()).Returns(@"covrun86"); - this.vanguardLocationProviderMock.Setup(u => u.GetVanguardProfilerX64Path()).Returns(@"covrun64"); - this.vanguardLocationProviderMock.Setup(u => u.GetVanguardProfilerConfigX86Path()).Returns(@"config86"); - this.vanguardLocationProviderMock.Setup(u => u.GetVanguardProfilerConfigX64Path()).Returns(@"config64"); - this.vanguardLocationProviderMock.Setup(u => u.GetClrInstrumentationEngineX86Path()).Returns(@"clrie86"); - this.vanguardLocationProviderMock.Setup(u => u.GetClrInstrumentationEngineX64Path()).Returns(@"clrie64"); - - this.implMock.Setup(i => i.CodeCoverageDepsJsonFilePath).Returns(@"C:\temp\codecoverage.deps.json"); - - this.environmentMock.Setup(e => e.OperatingSystem).Returns(PlatformOperatingSystem.Windows); - var configElement = DynamicCoverageDataCollectorImplTests.CreateXmlElement(DynamicCoverageDataCollectorTests.DefaultConfig); - this.collector.Initialize(configElement, this.eventsMock.Object, this.sinkMock.Object, this.loggerMock.Object, this.agentContextMock.Object); - } - - [TestCleanup] - public void CleanEnvVariables() - { - Environment.SetEnvironmentVariable("VANGUARD_CLR_IE_INSTRUMENTATION_NETCORE", null); - Environment.SetEnvironmentVariable("VANGUARD_CLR_IE_INSTRUMENTATION_NETFRAMEWORK", null); - } - - [TestMethod] - public void InitializeShouldNotThrowOnNullConfig() - { - XmlElement actualConfig = null; - this.implMock.Setup(i => i.Initialize( - It.IsAny(), - It.IsAny(), - It.IsAny())) - .Callback((config, sink, logger) => - { - actualConfig = config; - }); - - this.collector.Initialize(null, this.eventsMock.Object, this.sinkMock.Object, this.loggerMock.Object, this.agentContextMock.Object); - - Assert.IsNull(actualConfig); - } - - [TestMethod] - public void InitializeShouldLogWarningIfCurrentOperatingSystemIsUnix() - { - this.environmentMock.Setup(e => e.OperatingSystem).Returns(PlatformOperatingSystem.Unix); - this.collector = new TestableDynamicCoverageDataCollector(this.vanguardLocationProviderMock.Object, null, this.environmentMock.Object); - - this.collector.Initialize( - null, - this.eventsMock.Object, - this.sinkMock.Object, - this.loggerMock.Object, - this.agentContextMock.Object); - - var expectedExMsg = - "No code coverage data available. Code coverage is currently supported only on Windows."; - - this.loggerMock.Verify(l => l.LogWarning(It.IsAny(), expectedExMsg)); - } - - [TestMethod] - public void InitializeShouldNotRegisterForSessionEvents() - { - this.implMock = new Mock(); - this.environmentMock.Setup(e => e.OperatingSystem).Returns(PlatformOperatingSystem.Unix); - this.collector = new TestableDynamicCoverageDataCollector(this.vanguardLocationProviderMock.Object, null, this.environmentMock.Object); - - this.collector.Initialize( - null, - this.eventsMock.Object, - this.sinkMock.Object, - this.loggerMock.Object, - this.agentContextMock.Object); - - this.eventsMock.Raise(e => e.SessionStart += null, new SessionStartEventArgs()); - this.eventsMock.Raise(e => e.SessionEnd += null, new SessionEndEventArgs()); - - this.implMock.Verify(i => i.SessionStart(It.IsAny(), It.IsAny()), Times.Never); - this.implMock.Verify(i => i.SessionEnd(It.IsAny(), It.IsAny()), Times.Never); - } - - [TestMethod] - public void InitializeShouldRegisterForSessionStartEvent() - { - this.eventsMock.Raise(e => e.SessionStart += null, new SessionStartEventArgs()); - - this.implMock.Verify(i => i.SessionStart(It.IsAny(), It.IsAny())); - } - - [TestMethod] - public void InitializeShouldRegisterForSessionEndEvent() - { - this.eventsMock.Raise(e => e.SessionEnd += null, new SessionEndEventArgs()); - - this.implMock.Verify(i => i.SessionEnd(It.IsAny(), It.IsAny())); - } - - [TestMethod] - public void InitializeShouldNotLogMessageOnException() - { - var exceptionReason = "Failed to create directory"; - this.implMock.Setup(i => i.Initialize( - It.IsAny(), - It.IsAny(), - It.IsAny())) - .Throws(new Exception(exceptionReason)); - - var actualErrorMessage = string.Empty; - this.loggerMock.Setup(l => l.LogError(It.IsAny(), It.IsAny())) - .Callback((c, m) => { actualErrorMessage = m; }); - Assert.ThrowsException(() => this.collector.Initialize(null, this.eventsMock.Object, this.sinkMock.Object, this.loggerMock.Object, this.agentContextMock.Object)); - - this.loggerMock.Verify(l => l.LogError(It.IsAny(), It.IsAny()), Times.Once()); - - var expectedMessagePrefix = "Failed to initialize code coverage datacollector with error:"; - StringAssert.StartsWith(actualErrorMessage, expectedMessagePrefix); - StringAssert.Contains(actualErrorMessage, exceptionReason); - } - - [TestMethod] - public void GetEnvironmentVariablesShouldReturnRightEnvVaribles() - { - var expectedEnvVariables = new Dictionary - { - { "CORECLR_ENABLE_PROFILING", "1" }, - { "CORECLR_PROFILER_PATH_32", "covrun86" }, - { "CORECLR_PROFILER_PATH_64", "covrun64" }, - { "CORECLR_PROFILER", "{E5F256DC-7959-4DD6-8E4F-C11150AB28E0}" }, - { "CODE_COVERAGE_SESSION_NAME", "MTM_123" }, - { "COR_PROFILER_PATH_32", "covrun86" }, - { "COR_PROFILER_PATH_64", "covrun64" }, - { "COR_ENABLE_PROFILING", "1" }, - { "COR_PROFILER", "{E5F256DC-7959-4DD6-8E4F-C11150AB28E0}" }, - { "MicrosoftInstrumentationEngine_ConfigPath32_VanguardInstrumentationProfiler", "config86" }, - { "MicrosoftInstrumentationEngine_ConfigPath64_VanguardInstrumentationProfiler", "config64" }, - { "VANGUARD_DOTNET_ADDITIONAL_DEPS", @"C:\temp\codecoverage.deps.json" }, - }; - - this.implMock.Setup(i => i.GetSessionName()).Returns("MTM_123"); - - var envVars = this.collector.GetEnvironmentVariables(); - - VerifyEnvironmentVariables(expectedEnvVariables, envVars); - } - - [TestMethod] - public void GetEnvironmentVariablesShouldReturnRightEnvVariblesClrInstrumentationEngineEnabled() - { - var configElement = DynamicCoverageDataCollectorImplTests.CreateXmlElement(DynamicCoverageDataCollectorTests.ConfigWithClrIeEnabled); - this.collector.Initialize(configElement, this.eventsMock.Object, this.sinkMock.Object, this.loggerMock.Object, this.agentContextMock.Object); - - var expectedEnvVariables = new Dictionary - { - { "CORECLR_ENABLE_PROFILING", "1" }, - { "CORECLR_PROFILER_PATH_32", "clrie86" }, - { "CORECLR_PROFILER_PATH_64", "clrie64" }, - { "CORECLR_PROFILER", "{324F817A-7420-4E6D-B3C1-143FBED6D855}" }, - { "CODE_COVERAGE_SESSION_NAME", "MTM_123" }, - { "COR_PROFILER_PATH_32", "clrie86" }, - { "COR_PROFILER_PATH_64", "clrie64" }, - { "COR_ENABLE_PROFILING", "1" }, - { "COR_PROFILER", "{324F817A-7420-4E6D-B3C1-143FBED6D855}" }, - { "MicrosoftInstrumentationEngine_ConfigPath32_VanguardInstrumentationProfiler", "config86" }, - { "MicrosoftInstrumentationEngine_ConfigPath64_VanguardInstrumentationProfiler", "config64" }, - { "MicrosoftInstrumentationEngine_LogLevel", "Errors" }, - { "MicrosoftInstrumentationEngine_LogLevel_{2A1F2A34-8192-44AC-A9D8-4FCC03DCBAA8}", "Errors" }, - { "MicrosoftInstrumentationEngine_DisableCodeSignatureValidation", "1" }, - { "MicrosoftInstrumentationEngine_FileLogPath", @"GENERATED" }, - { "VANGUARD_DOTNET_ADDITIONAL_DEPS", @"C:\temp\codecoverage.deps.json" } - }; - - this.implMock.Setup(i => i.GetSessionName()).Returns("MTM_123"); - - var envVars = this.collector.GetEnvironmentVariables(); - - VerifyEnvironmentVariables(expectedEnvVariables, envVars); - } - - [TestMethod] - public void GetEnvironmentVariablesShouldReturnRightEnvVariblesClrInstrumentationEngineEnabledThroughEnvVars() - { - Environment.SetEnvironmentVariable("VANGUARD_CLR_IE_INSTRUMENTATION_NETCORE", "1"); - Environment.SetEnvironmentVariable("VANGUARD_CLR_IE_INSTRUMENTATION_NETFRAMEWORK", "1"); - - var configElement = DynamicCoverageDataCollectorImplTests.CreateXmlElement(DynamicCoverageDataCollectorTests.DefaultConfig); - this.collector.Initialize(configElement, this.eventsMock.Object, this.sinkMock.Object, this.loggerMock.Object, this.agentContextMock.Object); - - var expectedEnvVariables = new Dictionary - { - { "CORECLR_ENABLE_PROFILING", "1" }, - { "CORECLR_PROFILER_PATH_32", "clrie86" }, - { "CORECLR_PROFILER_PATH_64", "clrie64" }, - { "CORECLR_PROFILER", "{324F817A-7420-4E6D-B3C1-143FBED6D855}" }, - { "CODE_COVERAGE_SESSION_NAME", "MTM_123" }, - { "COR_PROFILER_PATH_32", "clrie86" }, - { "COR_PROFILER_PATH_64", "clrie64" }, - { "COR_ENABLE_PROFILING", "1" }, - { "COR_PROFILER", "{324F817A-7420-4E6D-B3C1-143FBED6D855}" }, - { "MicrosoftInstrumentationEngine_ConfigPath32_VanguardInstrumentationProfiler", "config86" }, - { "MicrosoftInstrumentationEngine_ConfigPath64_VanguardInstrumentationProfiler", "config64" }, - { "MicrosoftInstrumentationEngine_LogLevel", "Errors" }, - { "MicrosoftInstrumentationEngine_LogLevel_{2A1F2A34-8192-44AC-A9D8-4FCC03DCBAA8}", "Errors" }, - { "MicrosoftInstrumentationEngine_DisableCodeSignatureValidation", "1" }, - { "MicrosoftInstrumentationEngine_FileLogPath", @"GENERATED" }, - { "VANGUARD_DOTNET_ADDITIONAL_DEPS", @"C:\temp\codecoverage.deps.json" } - }; - - this.implMock.Setup(i => i.GetSessionName()).Returns("MTM_123"); - - var envVars = this.collector.GetEnvironmentVariables(); - - VerifyEnvironmentVariables(expectedEnvVariables, envVars); - } - - [TestMethod] - public void GetEnvironmentVariablesShouldReturnRightEnvVariblesClrInstrumentationEngineEnabledForNetCore() - { - var configElement = DynamicCoverageDataCollectorImplTests.CreateXmlElement(DynamicCoverageDataCollectorTests.ConfigWithClrIeEnabledForNetCore); - this.collector.Initialize(configElement, this.eventsMock.Object, this.sinkMock.Object, this.loggerMock.Object, this.agentContextMock.Object); - - var expectedEnvVariables = new Dictionary - { - { "CORECLR_ENABLE_PROFILING", "1" }, - { "CORECLR_PROFILER_PATH_32", "clrie86" }, - { "CORECLR_PROFILER_PATH_64", "clrie64" }, - { "CORECLR_PROFILER", "{324F817A-7420-4E6D-B3C1-143FBED6D855}" }, - { "CODE_COVERAGE_SESSION_NAME", "MTM_123" }, - { "COR_PROFILER_PATH_32", "covrun86" }, - { "COR_PROFILER_PATH_64", "covrun64" }, - { "COR_ENABLE_PROFILING", "1" }, - { "COR_PROFILER", "{E5F256DC-7959-4DD6-8E4F-C11150AB28E0}" }, - { "MicrosoftInstrumentationEngine_ConfigPath32_VanguardInstrumentationProfiler", "config86" }, - { "MicrosoftInstrumentationEngine_ConfigPath64_VanguardInstrumentationProfiler", "config64" }, - { "MicrosoftInstrumentationEngine_LogLevel", "Errors" }, - { "MicrosoftInstrumentationEngine_LogLevel_{2A1F2A34-8192-44AC-A9D8-4FCC03DCBAA8}", "Errors" }, - { "MicrosoftInstrumentationEngine_DisableCodeSignatureValidation", "1" }, - { "MicrosoftInstrumentationEngine_FileLogPath", @"GENERATED" } - }; - - this.implMock.Setup(i => i.GetSessionName()).Returns("MTM_123"); - - var envVars = this.collector.GetEnvironmentVariables(); - - VerifyEnvironmentVariables(expectedEnvVariables, envVars); - } - - [TestMethod] - public void GetEnvironmentVariablesShouldReturnRightEnvVariblesClrInstrumentationEngineEnabledForNetCoreThroughEnvVar() - { - Environment.SetEnvironmentVariable("VANGUARD_CLR_IE_INSTRUMENTATION_NETCORE", "1"); - Environment.SetEnvironmentVariable("VANGUARD_CLR_IE_INSTRUMENTATION_NETFRAMEWORK", "0"); - - var configElement = DynamicCoverageDataCollectorImplTests.CreateXmlElement(DynamicCoverageDataCollectorTests.DefaultConfig); - this.collector.Initialize(configElement, this.eventsMock.Object, this.sinkMock.Object, this.loggerMock.Object, this.agentContextMock.Object); - - var expectedEnvVariables = new Dictionary - { - { "CORECLR_ENABLE_PROFILING", "1" }, - { "CORECLR_PROFILER_PATH_32", "clrie86" }, - { "CORECLR_PROFILER_PATH_64", "clrie64" }, - { "CORECLR_PROFILER", "{324F817A-7420-4E6D-B3C1-143FBED6D855}" }, - { "CODE_COVERAGE_SESSION_NAME", "MTM_123" }, - { "COR_PROFILER_PATH_32", "covrun86" }, - { "COR_PROFILER_PATH_64", "covrun64" }, - { "COR_ENABLE_PROFILING", "1" }, - { "COR_PROFILER", "{E5F256DC-7959-4DD6-8E4F-C11150AB28E0}" }, - { "MicrosoftInstrumentationEngine_ConfigPath32_VanguardInstrumentationProfiler", "config86" }, - { "MicrosoftInstrumentationEngine_ConfigPath64_VanguardInstrumentationProfiler", "config64" }, - { "MicrosoftInstrumentationEngine_LogLevel", "Errors" }, - { "MicrosoftInstrumentationEngine_LogLevel_{2A1F2A34-8192-44AC-A9D8-4FCC03DCBAA8}", "Errors" }, - { "MicrosoftInstrumentationEngine_DisableCodeSignatureValidation", "1" }, - { "MicrosoftInstrumentationEngine_FileLogPath", @"GENERATED" }, - { "VANGUARD_DOTNET_ADDITIONAL_DEPS", @"C:\temp\codecoverage.deps.json" } - }; - - this.implMock.Setup(i => i.GetSessionName()).Returns("MTM_123"); - - var envVars = this.collector.GetEnvironmentVariables(); - - VerifyEnvironmentVariables(expectedEnvVariables, envVars); - } - - [TestMethod] - public void GetEnvironmentVariablesShouldReturnNoEnvVaribles() - { - this.implMock = new Mock(); - this.environmentMock.Setup(e => e.OperatingSystem).Returns(PlatformOperatingSystem.Unix); - this.collector = new TestableDynamicCoverageDataCollector(this.vanguardLocationProviderMock.Object, null, this.environmentMock.Object); - - this.collector.Initialize( - null, - this.eventsMock.Object, - this.sinkMock.Object, - this.loggerMock.Object, - this.agentContextMock.Object); - var envVars = this.collector.GetEnvironmentVariables(); - - Assert.IsFalse(envVars.Any(), "No environment variables set on unix."); - } - - [TestMethod] - public void DisposeShouldDisposeImpl() - { - this.collector.Dispose(); - this.implMock.Verify(i => i.Dispose()); - } - - [TestMethod] - public void DisposeShouldUnsubcribeEvents() - { - this.collector.Dispose(); - this.eventsMock.Raise(e => e.SessionStart += null, new SessionStartEventArgs()); - this.eventsMock.Raise(e => e.SessionEnd += null, new SessionEndEventArgs()); - - this.implMock.Verify(i => i.SessionStart(It.IsAny(), It.IsAny()), Times.Never); - this.implMock.Verify(i => i.SessionEnd(It.IsAny(), It.IsAny()), Times.Never); - } - - private static void VerifyEnvironmentVariables(Dictionary expectedEnvVariables, IEnumerable> envVars) - { - foreach (var pair in envVars) - { - Console.WriteLine(pair.Key + " ==> " + pair.Value); - } - - Assert.AreEqual(expectedEnvVariables.Count, envVars.Count()); - - foreach (var pair in envVars) - { - Assert.IsTrue(expectedEnvVariables.ContainsKey(pair.Key), $"unexpected env variable {pair}"); - Assert.IsTrue(pair.Key == "MicrosoftInstrumentationEngine_FileLogPath" || expectedEnvVariables[pair.Key].Equals(pair.Value), $"unexpected env variable {pair}"); - } - } - - private class TestableDynamicCoverageDataCollector : DynamicCoverageDataCollector - { - public TestableDynamicCoverageDataCollector( - IProfilersLocationProvider vanguardLocationProvider, - IDynamicCoverageDataCollectorImpl impl, - IEnvironment environment) - : base(vanguardLocationProvider, impl, environment) - { - } - - public new IEnumerable> GetEnvironmentVariables() - { - return base.GetEnvironmentVariables(); - } - } - } -} diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/Microsoft.TestPlatform.TraceDataCollector.UnitTests.csproj b/test/DataCollectors/TraceDataCollector.UnitTests/Microsoft.TestPlatform.TraceDataCollector.UnitTests.csproj deleted file mode 100644 index c38d997b27..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/Microsoft.TestPlatform.TraceDataCollector.UnitTests.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - ..\..\..\ - true - true - - - - Microsoft.VisualStudio.TraceDataCollector.UnitTests - - - netcoreapp2.1 - true - true - Exe - Microsoft.TestPlatform.TraceDataCollector.UnitTests - - - - - - - - - - - - - diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/ProfilersLocationProviderTests.cs b/test/DataCollectors/TraceDataCollector.UnitTests/ProfilersLocationProviderTests.cs deleted file mode 100644 index 74a3c46ac1..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/ProfilersLocationProviderTests.cs +++ /dev/null @@ -1,119 +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. - -namespace Microsoft.VisualStudio.TraceDataCollector.UnitTests -{ - using System; - using System.IO; - using System.Reflection; - using TestTools.UnitTesting; - using TraceCollector; - - [TestClass] - [TestCategory("Windows")] - public class ProfilersLocationProviderTests - { - private ProfilersLocationProvider vanguardLocationProvider; - - public ProfilersLocationProviderTests() - { - this.vanguardLocationProvider = new ProfilersLocationProvider(); - } - - [TestCleanup] - public void CleanEnvVariables() - { - Environment.SetEnvironmentVariable("CLRIEX86InstallDir", null); - Environment.SetEnvironmentVariable("CLRIEX64InstallDir", null); - } - - [TestMethod] - public void GetVanguardPathShouldReturnRightPath() - { - var actualPath = this.vanguardLocationProvider.GetVanguardPath(); - - Assert.AreEqual(Path.Join(this.GetCurrentAssemblyLocation(), @"CodeCoverage\CodeCoverage.exe"), actualPath); - } - - [TestMethod] - public void GetVanguardProfilerX86PathShouldReturnRightDirectory() - { - var actualPath = this.vanguardLocationProvider.GetVanguardProfilerX86Path(); - - Assert.AreEqual(Path.Join(this.GetCurrentAssemblyLocation(), @"CodeCoverage\covrun32.dll"), actualPath); - } - - [TestMethod] - public void GetVanguardProfilerX64PathShouldReturnRightDirectory() - { - var actualPath = this.vanguardLocationProvider.GetVanguardProfilerX64Path(); - - Assert.AreEqual(Path.Join(this.GetCurrentAssemblyLocation(), @"CodeCoverage\amd64\covrun64.dll"), actualPath); - } - - [TestMethod] - public void GetVanguardProfilerConfigX86PathShouldReturnRightDirectory() - { - var actualPath = this.vanguardLocationProvider.GetVanguardProfilerConfigX86Path(); - - Assert.AreEqual(Path.Join(this.GetCurrentAssemblyLocation(), @"CodeCoverage\VanguardInstrumentationProfiler_x86.config"), actualPath); - } - - [TestMethod] - public void GetVanguardProfilerConfigX64PathShouldReturnRightDirectory() - { - var actualPath = this.vanguardLocationProvider.GetVanguardProfilerConfigX64Path(); - - Assert.AreEqual(Path.Join(this.GetCurrentAssemblyLocation(), @"CodeCoverage\amd64\VanguardInstrumentationProfiler_x64.config"), actualPath); - } - - [TestMethod] - public void GetCodeCoverageShimPathShouldReturnRightDirectory() - { - var actualPath = this.vanguardLocationProvider.GetCodeCoverageShimPath(); - - Assert.AreEqual(Path.Join(this.GetCurrentAssemblyLocation(), @"CodeCoverage\coreclr\Microsoft.VisualStudio.CodeCoverage.Shim.dll"), actualPath); - } - - [TestMethod] - public void GetClrInstrumentationEngineX86PathShouldReturnRightDirectory() - { - var actualDir = this.vanguardLocationProvider.GetClrInstrumentationEngineX86Path(); - - Assert.AreEqual(Path.Join(this.GetCurrentAssemblyLocation(), @"InstrumentationEngine\x86\MicrosoftInstrumentationEngine_x86.dll"), actualDir); - } - - [TestMethod] - public void GetClrInstrumentationEngineX64PathShouldReturnRightDirectory() - { - var actualDir = this.vanguardLocationProvider.GetClrInstrumentationEngineX64Path(); - - Assert.AreEqual(Path.Join(this.GetCurrentAssemblyLocation(), @"InstrumentationEngine\x64\MicrosoftInstrumentationEngine_x64.dll"), actualDir); - } - - [TestMethod] - public void GetClrInstrumentationEngineX86PathShouldReturnRightDirectoryIfEnvVariableSet() - { - Environment.SetEnvironmentVariable("CLRIEX86InstallDir", @"C:\temp"); - - var actualDir = this.vanguardLocationProvider.GetClrInstrumentationEngineX86Path(); - - Assert.AreEqual(@"C:\temp\MicrosoftInstrumentationEngine_x86.dll", actualDir); - } - - [TestMethod] - public void GetClrInstrumentationEngineX64PathShouldReturnRightDirectoryIfEnvVariableSet() - { - Environment.SetEnvironmentVariable("CLRIEX64InstallDir", @"C:\temp"); - - var actualDir = this.vanguardLocationProvider.GetClrInstrumentationEngineX64Path(); - - Assert.AreEqual(@"C:\temp\MicrosoftInstrumentationEngine_x64.dll", actualDir); - } - - private string GetCurrentAssemblyLocation() - { - return Path.GetDirectoryName(typeof(ProfilersLocationProviderTests).GetTypeInfo().Assembly.Location); - } - } -} diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/Program.cs b/test/DataCollectors/TraceDataCollector.UnitTests/Program.cs deleted file mode 100644 index 7f39953476..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/Program.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. - -namespace Microsoft.VisualStudio.TestPlatform.Common.DataCollector.UnitTests -{ - /// - /// Main entry point for the command line runner. - /// - public static class Program - { - public static void Main(string[] args) - { - } - } -} \ No newline at end of file diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/Properties/AssemblyInfo.cs b/test/DataCollectors/TraceDataCollector.UnitTests/Properties/AssemblyInfo.cs deleted file mode 100644 index fb892d21e1..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,21 +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.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("datacollector.UnitTests")] -[assembly: AssemblyTrademark("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("00aa21f3-31e4-4748-ac0b-c4eadb41ca24")] diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/VanguardCommandBuilderTests.cs b/test/DataCollectors/TraceDataCollector.UnitTests/VanguardCommandBuilderTests.cs deleted file mode 100644 index 26b9e6ec94..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/VanguardCommandBuilderTests.cs +++ /dev/null @@ -1,50 +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. - -namespace Microsoft.VisualStudio.TraceDataCollector.UnitTests -{ - using Coverage; - using Coverage.Interfaces; - using TestTools.UnitTesting; - - [TestClass] - public class VanguardCommandBuilderTests - { - private VanguardCommandBuilder vanguardCommandBuilder; - - public VanguardCommandBuilderTests() - { - this.vanguardCommandBuilder = new VanguardCommandBuilder(); - } - - [TestMethod] - public void GenerateCommandLineShouldReturnCommandForCollectCommand() - { - string sessionName = "session1", outputName = "output1", configFileName = "configFileName1"; - string expectedCommand = $"collect /session:{sessionName} /output:\"{outputName}\" /config:\"{configFileName}\""; - - var actualCommand = this.vanguardCommandBuilder.GenerateCommandLine( - VanguardCommand.Collect, - sessionName, - outputName, - configFileName); - - Assert.AreEqual(expectedCommand, actualCommand); - } - - [TestMethod] - public void GenerateCommandLineShouldReturnCommandForShutdownCommand() - { - string sessionName = "session1"; - string expectedCommand = $"shutdown /session:{sessionName}"; - - var actualCommand = this.vanguardCommandBuilder.GenerateCommandLine( - VanguardCommand.Shutdown, - sessionName, - null, - null); - - Assert.AreEqual(expectedCommand, actualCommand); - } - } -} diff --git a/test/DataCollectors/TraceDataCollector.UnitTests/VanguardTests.cs b/test/DataCollectors/TraceDataCollector.UnitTests/VanguardTests.cs deleted file mode 100644 index e4d567e866..0000000000 --- a/test/DataCollectors/TraceDataCollector.UnitTests/VanguardTests.cs +++ /dev/null @@ -1,204 +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. - -namespace Microsoft.VisualStudio.TraceDataCollector.UnitTests -{ - using System; - using System.ComponentModel; - using System.Globalization; - using System.IO; - using System.Text; - using System.Threading; - using Coverage; - using Coverage.Interfaces; - using global::TestPlatform.TestUtilities; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - using TestPlatform.CoreUtilities.Helpers; - using TestPlatform.ObjectModel; - using TestPlatform.ObjectModel.DataCollection; - using TraceCollector; - using TraceCollector.Interfaces; - - [TestClass] - [TestCategory("Windows")] - public class VanguardTests - { - private const string CodeCoverageExeFileName = "CodeCoverage"; - private const string ConfigFileNameFormat = - @"{0}\{1}\CodeCoverage.config"; // {TempDirPath}\{Session_GUID}\CodeCoverage.config - - private const string ConfigXml = - @" - - - .*Tests.dll - - - True - True - True - False - - "; - - private Vanguard vanguard; - private string sessionName; - private string configFileName; - private Mock dataCollectionLoggerMock; - private Mock vanguardLocationProviderMock; - private string outputFileName; - private string outputDir; - private DataCollectionContext dataCollectionContext; - private Mock vanguardCommandBuilderMock; - private IProcessJobObject processJobObject; - - public VanguardTests() - { - TestCase testcase = new TestCase { Id = Guid.NewGuid() }; - this.dataCollectionContext = new DataCollectionContext(testcase); - this.dataCollectionLoggerMock = new Mock(); - this.processJobObject = new ProcessJobObject(); - this.vanguardCommandBuilderMock = new Mock(); - this.vanguardLocationProviderMock = new Mock(); - - this.vanguard = new Vanguard(this.vanguardLocationProviderMock.Object, this.vanguardCommandBuilderMock.Object, this.processJobObject); - this.sessionName = Guid.NewGuid().ToString(); - this.configFileName = string.Format(VanguardTests.ConfigFileNameFormat, Path.GetTempPath(), this.sessionName); - this.outputDir = Path.GetDirectoryName(this.configFileName); - Directory.CreateDirectory(this.outputDir); - File.WriteAllText(this.configFileName, VanguardTests.ConfigXml); - this.outputFileName = Path.Combine(this.outputDir, Guid.NewGuid() + ".coverage"); - this.vanguardCommandBuilderMock.Setup(c => - c.GenerateCommandLine(VanguardCommand.Shutdown, this.sessionName, It.IsAny(), It.IsAny())) - .Returns(VanguardTests.GetShutdownCommand(this.sessionName)); - this.vanguard.Initialize(this.sessionName, this.configFileName, this.dataCollectionLoggerMock.Object); - this.vanguardLocationProviderMock.Setup(c => c.GetVanguardPath()).Returns(Path.Combine(Directory.GetCurrentDirectory(), "CodeCoverage", "CodeCoverage.exe")); - } - - [TestCleanup] - public void Cleanup() - { - Environment.SetEnvironmentVariable(EnvironmentHelper.VstestConnectionTimeout, string.Empty); - this.vanguard.Stop(); - File.Delete(this.configFileName); - Directory.Delete(this.outputDir, true); - } - - [TestMethod] - public void InitializeShouldCreateConfigFile() - { - Assert.IsTrue(File.Exists(this.configFileName)); - StringAssert.Contains( - VanguardTests.ConfigXml.Replace(" ", string.Empty).Replace(Environment.NewLine, string.Empty), - File.ReadAllText(this.configFileName).Replace(" ", string.Empty).Replace(Environment.NewLine, string.Empty)); - } - - [Ignore] - [TestMethod] - public void StartShouldStartVanguardProcessWithCollectCommand() - { - var cts = new CancellationTokenSource(); - var numOfProcessCreatedTask = NumberOfProcessLaunchedUtility.NumberOfProcessCreated( - cts, - VanguardTests.CodeCoverageExeFileName); - - this.vanguardCommandBuilderMock.Setup(c => - c.GenerateCommandLine(VanguardCommand.Collect, It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(VanguardTests.GetCollectCommand(this.sessionName, this.outputFileName, this.configFileName)); - - this.vanguard.Start(this.outputFileName, this.dataCollectionContext); - cts.Cancel(); - - var numOfProcessCreated = numOfProcessCreatedTask.Result.Count; - - // TODO find the reason why additional process launched when collecting code coverage. - Assert.IsTrue(numOfProcessCreated == 1 || numOfProcessCreated == 2, $"Number of process created:{numOfProcessCreated} expected is 1 or 2."); - } - - [TestMethod] - [ExpectedException(typeof(Win32Exception))] - public void StartShouldThrowOnInvalidVarguardPath() - { - this.vanguardLocationProviderMock.Setup(c => c.GetVanguardPath()).Returns(Path.Combine(Directory.GetCurrentDirectory(), "WrongExePath.exe")); - this.vanguard.Start(this.outputFileName, this.dataCollectionContext); - } - - [TestMethod] - public void StartShouldThrowOnInvalidCommandLine() - { - var expectedErrorMessage = - "Running event not received from CodeCoverage.exe. Check eventlogs for failure reason."; - this.vanguardCommandBuilderMock - .Setup(c => c.GenerateCommandLine( - VanguardCommand.Collect, - It.IsAny(), - It.IsAny(), - It.IsAny())).Returns("invalid command"); - var exception = Assert.ThrowsException(() => this.vanguard.Start(this.outputFileName, this.dataCollectionContext)); - Assert.AreEqual(expectedErrorMessage, exception.Message); - } - - [TestMethod] - [Ignore("This test is flaky")] - public void StartShouldThrowOnTimeout() - { - Environment.SetEnvironmentVariable(EnvironmentHelper.VstestConnectionTimeout, "0"); - var expectedErrorMessage = - "Failed to receive running event from CodeCoverage.exe in 0 seconds, This may occur due to machine slowness, please set environment variable VSTEST_CONNECTION_TIMEOUT to increase timeout."; - this.vanguardCommandBuilderMock - .Setup(c => c.GenerateCommandLine( - VanguardCommand.Collect, - It.IsAny(), - It.IsAny(), - It.IsAny())).Returns(VanguardTests.GetCollectCommand(this.sessionName, this.outputFileName, this.configFileName)); - var exception = Assert.ThrowsException(() => this.vanguard.Start(this.outputFileName, this.dataCollectionContext)); - Assert.AreEqual(expectedErrorMessage, exception.Message); - } - - [Ignore] - [TestMethod] - public void StopShouldLaunchVarguardWithShutdownCommand() - { - var cts = new CancellationTokenSource(); - var numOfProcessCreatedTask = NumberOfProcessLaunchedUtility.NumberOfProcessCreated( - cts, - VanguardTests.CodeCoverageExeFileName); - this.vanguardCommandBuilderMock - .Setup(c => c.GenerateCommandLine( - VanguardCommand.Collect, - It.IsAny(), - It.IsAny(), - It.IsAny())).Returns(VanguardTests.GetCollectCommand(this.sessionName, this.outputFileName, this.configFileName)); - this.vanguard.Start(this.outputFileName, this.dataCollectionContext); - this.vanguard.Stop(); - cts.Cancel(); - - var numOfProcessCreated = numOfProcessCreatedTask.Result.Count; - - // TODO find the reason why additional process launched when collecting code coverage. - Assert.IsTrue(numOfProcessCreated == 2 || numOfProcessCreated == 4, $"Number of process created:{numOfProcessCreated} expected is 2 or 4."); - } - - private static string GetCollectCommand(string sessionName, string outputName, string configurationFileName) - { - StringBuilder builder = new StringBuilder(); - builder.AppendFormat( - CultureInfo.InvariantCulture, - "collect /session:{0} /output:\"{1}\" /config:\"{2}\"", - sessionName, - outputName, - configurationFileName); - - return builder.ToString(); - } - - private static string GetShutdownCommand(string sessionName) - { - StringBuilder builder = new StringBuilder(); - builder.AppendFormat(CultureInfo.InvariantCulture, "shutdown /session:{0}", sessionName); - - return builder.ToString(); - } - } -} diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/CodeCoverageTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/CodeCoverageTests.cs index 06f6038722..53c191bc10 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/CodeCoverageTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/CodeCoverageTests.cs @@ -204,7 +204,7 @@ private string CreateArguments( var assemblyPaths = this.GetAssetFullPath(testParameters.AssemblyName); string traceDataCollectorDir = Path.Combine(IntegrationTestEnvironment.TestPlatformRootDirectory, - "src", "DataCollectors", "TraceDataCollector", "bin", IntegrationTestEnvironment.BuildConfiguration, "netstandard2.0"); + "artifacts", IntegrationTestEnvironment.BuildConfiguration, "Microsoft.CodeCoverage"); string diagFileName = Path.Combine(this.resultsDirectory, "diaglog.txt"); var arguments = PrepareArguments(assemblyPaths, this.GetTestAdapterPath(), string.Empty, From b51c407799bd09b57d5397c1b6cf8c527be9aa6f Mon Sep 17 00:00:00 2001 From: fhnaseer Date: Fri, 18 Dec 2020 09:47:40 +0100 Subject: [PATCH 11/46] Adding environment variable used during build process, (#2679) * Removing TraceDataCollector project, * Getting tracedatacollector from nuget, * Removing signing of codecoverage libs as they are already signed, updating codecoverage version, * fixing path to tracedatacollector, * Fixing acceptance tests, * Setting TraceDataCollectorPackagesDir vairable which is used in pipeline, * Fixing environment variable, * Fixing path, once again, Co-authored-by: faisal --- scripts/vsts-prebuild.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/vsts-prebuild.ps1 b/scripts/vsts-prebuild.ps1 index 9fe4025d54..b0bde0c730 100644 --- a/scripts/vsts-prebuild.ps1 +++ b/scripts/vsts-prebuild.ps1 @@ -43,3 +43,7 @@ Write-Host "##vso[task.setvariable variable=JsonNetVersion;]$JsonNetVersion" $microsoftFakesVersion = ([xml](Get-Content $TP_ROOT_DIR\scripts\build\TestPlatform.Dependencies.props)).Project.PropertyGroup.MicrosoftFakesVersion $FakesPackageDir = Join-Path $TP_ROOT_DIR "packages\Microsoft.QualityTools.Testing.Fakes.TestRunnerHarness\$microsoftFakesVersion\contentFiles" Write-Host "##vso[task.setvariable variable=FakesPackageDir;]$FakesPackageDir" + +$codeCoverageExternalsVersion = ([xml](Get-Content $TP_ROOT_DIR\scripts\build\TestPlatform.Dependencies.props)).Project.PropertyGroup.CodeCoverageExternalsVersion +$TraceDataCollectorPackagesDir = Join-Path $TP_ROOT_DIR "packages\microsoft.visualstudio.tracedatacollector\$codeCoverageExternalsVersion\lib" +Write-Host "##vso[task.setvariable variable=TraceDataCollectorPackagesDir;]$TraceDataCollectorPackagesDir" \ No newline at end of file From 4f594fcab18869e7aee431450adeff58b1b74b76 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 22 Dec 2020 10:35:34 +0100 Subject: [PATCH 12/46] Update dependencies from https://github.com/dotnet/arcade build 20201221.2 (#2680) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.SwaggerGenerator.MSBuild From Version 1.0.0-beta.20580.3 -> To Version 1.0.0-beta.20621.2 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 6 +++--- global.json | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/NuGet.config b/NuGet.config index 95f0f7b047..cb1a9eed0c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -16,7 +16,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c0db89e933..4a55833a5f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,25 +3,25 @@ - + https://github.com/dotnet/arcade - 7ee8c2b620e66b3762d7a5a688dee8238770c86a + ac42bf1c800b896125632aa845f961e391d1a440 - + https://github.com/dotnet/arcade - 7ee8c2b620e66b3762d7a5a688dee8238770c86a + ac42bf1c800b896125632aa845f961e391d1a440 - + https://github.com/dotnet/arcade - 7ee8c2b620e66b3762d7a5a688dee8238770c86a + ac42bf1c800b896125632aa845f961e391d1a440 - + https://github.com/dotnet/arcade - 7ee8c2b620e66b3762d7a5a688dee8238770c86a + ac42bf1c800b896125632aa845f961e391d1a440 - + https://github.com/dotnet/arcade - 7ee8c2b620e66b3762d7a5a688dee8238770c86a + ac42bf1c800b896125632aa845f961e391d1a440 https://github.com/dotnet/arcade-services diff --git a/eng/Versions.props b/eng/Versions.props index 1a2aa5a737..d1bc0a12b6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,8 +60,8 @@ 2.4.1 2.0.3 2.4.1 - 2.2.0-beta.20580.3 - 1.0.0-beta.20580.3 + 2.2.0-beta.20621.2 + 1.0.0-beta.20621.2 1.22.0 1.1.2 2.0.0 @@ -73,7 +73,7 @@ 1.7.0 1.1.0-beta.19556.4 1.0.0-beta2-19554-01 - 1.0.0-beta.20580.3 + 1.0.0-beta.20621.2 1.0.0-beta.20055.1 - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/package/nuspec/Microsoft.TestPlatform.nuspec b/src/package/nuspec/Microsoft.TestPlatform.nuspec index ca6d401d14..21306928ca 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.nuspec @@ -109,7 +109,6 @@ - @@ -266,20 +265,38 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/package/sign/sign.proj b/src/package/sign/sign.proj index ee7aae7ba3..4ea8ef5a88 100644 --- a/src/package/sign/sign.proj +++ b/src/package/sign/sign.proj @@ -131,11 +131,9 @@ - - From 711cec75e2fb98893365ce479492d04a3d75ab97 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 15 Jan 2021 14:55:42 +0100 Subject: [PATCH 25/46] Update dependencies from https://github.com/dotnet/arcade build 20210113.4 (#2696) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.SwaggerGenerator.MSBuild From Version 1.0.0-beta.20621.2 -> To Version 1.0.0-beta.21063.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 +++++++++---------- eng/Versions.props | 6 +++--- .../templates/post-build/post-build.yml | 12 +++++++++++ global.json | 4 ++-- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4a55833a5f..1980fd0e7d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,25 +3,25 @@ - + https://github.com/dotnet/arcade - ac42bf1c800b896125632aa845f961e391d1a440 + d01f08a47a14c3842f5f74e14e6a6a8b7b7a5593 - + https://github.com/dotnet/arcade - ac42bf1c800b896125632aa845f961e391d1a440 + d01f08a47a14c3842f5f74e14e6a6a8b7b7a5593 - + https://github.com/dotnet/arcade - ac42bf1c800b896125632aa845f961e391d1a440 + d01f08a47a14c3842f5f74e14e6a6a8b7b7a5593 - + https://github.com/dotnet/arcade - ac42bf1c800b896125632aa845f961e391d1a440 + d01f08a47a14c3842f5f74e14e6a6a8b7b7a5593 - + https://github.com/dotnet/arcade - ac42bf1c800b896125632aa845f961e391d1a440 + d01f08a47a14c3842f5f74e14e6a6a8b7b7a5593 https://github.com/dotnet/arcade-services diff --git a/eng/Versions.props b/eng/Versions.props index d1bc0a12b6..3d2209c4b3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,8 +60,8 @@ 2.4.1 2.0.3 2.4.1 - 2.2.0-beta.20621.2 - 1.0.0-beta.20621.2 + 2.2.0-beta.21063.4 + 1.0.0-beta.21063.4 1.22.0 1.1.2 2.0.0 @@ -73,7 +73,7 @@ 1.7.0 1.1.0-beta.19556.4 1.0.0-beta2-19554-01 - 1.0.0-beta.20621.2 + 1.0.0-beta.21063.4 1.0.0-beta.20055.1 - 3.4.3 + 5.8.1 All diff --git a/src/package/nuspec/Microsoft.CodeCoverage.nuspec b/src/package/nuspec/Microsoft.CodeCoverage.nuspec index 64e6ff9af3..ac1e347e9c 100644 --- a/src/package/nuspec/Microsoft.CodeCoverage.nuspec +++ b/src/package/nuspec/Microsoft.CodeCoverage.nuspec @@ -1,5 +1,5 @@ - + Microsoft.CodeCoverage $Version$ @@ -10,12 +10,23 @@ Microsoft.CodeCoverage package brings infra for collecting code coverage from vstest.console.exe and "dotnet test". http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing codecoverage code-coverage + + + + + + + diff --git a/src/package/nuspec/Microsoft.NET.Test.Sdk.nuspec b/src/package/nuspec/Microsoft.NET.Test.Sdk.nuspec index ba59062cb5..a98d7a64eb 100644 --- a/src/package/nuspec/Microsoft.NET.Test.Sdk.nuspec +++ b/src/package/nuspec/Microsoft.NET.Test.Sdk.nuspec @@ -1,5 +1,5 @@ - + Microsoft.NET.Test.Sdk $Version$ @@ -9,10 +9,15 @@ true http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png The MSbuild targets and properties for building .NET test projects. © Microsoft Corporation. All rights reserved. https://github.com/microsoft/vstest/ vstest visual-studio unittest testplatform mstest microsoft test testing + @@ -30,6 +35,7 @@ + @@ -37,15 +43,24 @@ + + + + + + + + + diff --git a/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec b/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec index 579a948c62..5daced586d 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec @@ -1,5 +1,5 @@  - + Microsoft.TestPlatform.Portable 15.0.0 @@ -11,11 +11,18 @@ This package contains a subset of binaries for the Visual Studio Test Platform (vstest). vstest provides a modern, cross platform testing engine that also powers the testing on .NET Core. Supports the following popular test frameworks - MSTest v2, xUnit and Nunit with support for extensibility. https://www.visualstudio.com/microsoft-visual-studio-test-platform http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing + + + diff --git a/src/package/nuspec/Microsoft.TestPlatform.nuspec b/src/package/nuspec/Microsoft.TestPlatform.nuspec index 21306928ca..1e0e3b6103 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.nuspec @@ -1,5 +1,5 @@  - + Microsoft.TestPlatform 15.0.0 @@ -11,11 +11,18 @@ This package contains the full set of binaries for the Visual Studio Test Platform (vstest). It provides a modern, cross platform testing engine that powers the testing on .NET Core as well. It integrates with popular test frameworks like MSTest(v1 and v2), xUnit and Nunit with support for extensibility. https://www.visualstudio.com/microsoft-visual-studio-test-platform http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing + + + diff --git a/src/package/nuspec/TestPlatform.Build.nuspec b/src/package/nuspec/TestPlatform.Build.nuspec index 92c0d9d73b..79dc3c3341 100644 --- a/src/package/nuspec/TestPlatform.Build.nuspec +++ b/src/package/nuspec/TestPlatform.Build.nuspec @@ -1,5 +1,5 @@  - + Microsoft.TestPlatform.Build 15.0.0 @@ -10,11 +10,22 @@ Build tasks and targets for running tests with Test Platform http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing + + + + + + + diff --git a/src/package/nuspec/TestPlatform.CLI.nuspec b/src/package/nuspec/TestPlatform.CLI.nuspec index ce0da80674..57a9d36ade 100644 --- a/src/package/nuspec/TestPlatform.CLI.nuspec +++ b/src/package/nuspec/TestPlatform.CLI.nuspec @@ -1,5 +1,5 @@  - + Microsoft.TestPlatform.CLI 15.0.0 @@ -10,14 +10,22 @@ The cross platform Microsoft Test Platform. http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing + + + + diff --git a/src/package/nuspec/TestPlatform.Extensions.TrxLogger.nuspec b/src/package/nuspec/TestPlatform.Extensions.TrxLogger.nuspec index 4ff5a3cbbf..94d86b5633 100644 --- a/src/package/nuspec/TestPlatform.Extensions.TrxLogger.nuspec +++ b/src/package/nuspec/TestPlatform.Extensions.TrxLogger.nuspec @@ -1,5 +1,5 @@ - + Microsoft.TestPlatform.Extensions.TrxLogger 15.0.0 @@ -10,9 +10,15 @@ C# SDK for the test platform protocol. This SDK can be used in IDE or Editors to use test platform for discovery and execution of tests. http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing + + @@ -33,6 +39,8 @@ + + diff --git a/src/package/nuspec/TestPlatform.ObjectModel.nuspec b/src/package/nuspec/TestPlatform.ObjectModel.nuspec index f1b881146b..e76d1096e8 100644 --- a/src/package/nuspec/TestPlatform.ObjectModel.nuspec +++ b/src/package/nuspec/TestPlatform.ObjectModel.nuspec @@ -1,5 +1,5 @@  - + Microsoft.TestPlatform.ObjectModel 15.0.0 @@ -10,9 +10,15 @@ The Microsoft Test Platform Object Model. http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing + + @@ -76,6 +82,8 @@ + + diff --git a/src/package/nuspec/TestPlatform.TestHost.nuspec b/src/package/nuspec/TestPlatform.TestHost.nuspec index a3896fc778..15839c44cc 100644 --- a/src/package/nuspec/TestPlatform.TestHost.nuspec +++ b/src/package/nuspec/TestPlatform.TestHost.nuspec @@ -1,5 +1,5 @@  - + Microsoft.TestPlatform.TestHost $Version$ @@ -10,9 +10,15 @@ Testplatform host executes the test using specified adapter. http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing + + @@ -25,7 +31,6 @@ - @@ -38,12 +43,18 @@ + + + + + + diff --git a/src/package/nuspec/TestPlatform.TranslationLayer.nuspec b/src/package/nuspec/TestPlatform.TranslationLayer.nuspec index ad12872f4f..62d30c85e4 100644 --- a/src/package/nuspec/TestPlatform.TranslationLayer.nuspec +++ b/src/package/nuspec/TestPlatform.TranslationLayer.nuspec @@ -1,5 +1,5 @@  - + Microsoft.TestPlatform.TranslationLayer 15.0.0 @@ -10,9 +10,15 @@ C# SDK for the test platform protocol. This SDK can be used in IDE or Editors to use test platform for discovery and execution of tests. http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png https://github.com/microsoft/vstest/ © Microsoft Corporation. All rights reserved. vstest visual-studio unittest testplatform mstest microsoft test testing + + @@ -30,6 +36,8 @@ + + diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TestPlatformNugetPackageTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TestPlatformNugetPackageTests.cs index 57ce0f7d8f..384215d185 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TestPlatformNugetPackageTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TestPlatformNugetPackageTests.cs @@ -25,8 +25,15 @@ public static void ClassInit(TestContext testContext) nugetPackageFolder = Path.Combine(packageLocation, Path.GetFileNameWithoutExtension(nugetPackage)); ZipFile.ExtractToDirectory(nugetPackage, nugetPackageFolder); - Directory.Move(Path.Combine(nugetPackageFolder, "tools", "net451", "Team%20Tools"), Path.Combine(nugetPackageFolder, "tools", "net451", "Team Tools")); - Directory.Move(Path.Combine(nugetPackageFolder, "tools", "net451", "Team Tools", "Dynamic%20Code%20Coverage%20Tools"), Path.Combine(nugetPackageFolder, "tools", "net451", "Team Tools", "Dynamic Code Coverage Tools")); + TryMoveDirectory( + sourceDirName: Path.Combine(nugetPackageFolder, "tools", "net451", "Team%20Tools"), + destDirName: Path.Combine(nugetPackageFolder, "tools", "net451", "Team Tools") + ); + + TryMoveDirectory( + sourceDirName: Path.Combine(nugetPackageFolder, "tools", "net451", "Team Tools", "Dynamic%20Code%20Coverage%20Tools"), + destDirName: Path.Combine(nugetPackageFolder, "tools", "net451", "Team Tools", "Dynamic Code Coverage Tools") + ); } [ClassCleanup] @@ -97,5 +104,13 @@ private string CreateCodeCoverageArguments( return arguments; } + + private static void TryMoveDirectory(string sourceDirName, string destDirName) + { + if (Directory.Exists(sourceDirName)) + { + Directory.Move(sourceDirName, destDirName); + } + } } } diff --git a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs index 947ad4b53d..62e8031dd0 100644 --- a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs +++ b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs @@ -17,7 +17,8 @@ namespace Microsoft.TestPlatform.TestUtilities /// public class IntegrationTestEnvironment { - public static string TestPlatformRootDirectory = Environment.GetEnvironmentVariable("TP_ROOT_DIR"); + public static string TestPlatformRootDirectory = Environment.GetEnvironmentVariable("TP_ROOT_DIR") + ?? Path.GetFullPath(@"..\..\..\..\..".Replace('\\', Path.DirectorySeparatorChar)); private static Dictionary dependencyVersions; From c7fa1865dd4584b2a7e0cf4ca095d1c6df570d95 Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Tue, 26 Jan 2021 22:32:53 +0100 Subject: [PATCH 41/46] vstest.console: CommandLineOptions: preserve stacktrace on re-throw (CA2200) (#2606) * vstest.console: CommandLineOptions: preserve stacktrace on re-throw (CA2200) --- src/vstest.console/CommandLine/CommandLineOptions.cs | 10 +++------- .../CommandLine/TestSourceException.cs | 12 +++++++++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/vstest.console/CommandLine/CommandLineOptions.cs b/src/vstest.console/CommandLine/CommandLineOptions.cs index 64d212043b..4edd13929b 100644 --- a/src/vstest.console/CommandLine/CommandLineOptions.cs +++ b/src/vstest.console/CommandLine/CommandLineOptions.cs @@ -295,14 +295,10 @@ public void AddSource(string source) // Get matching files from file pattern parser matchingFiles = FilePatternParser.GetMatchingFiles(source); } - catch(TestSourceException ex) + catch(TestSourceException ex) when (source.StartsWith("-") || source.StartsWith("/")) { - if(source.StartsWith("-") || source.StartsWith("/")) - { - throw new TestSourceException( - string.Format(CultureInfo.CurrentUICulture, CommandLineResources.InvalidArgument, source)); - } - throw ex; + throw new TestSourceException( + string.Format(CultureInfo.CurrentUICulture, CommandLineResources.InvalidArgument, source), ex); } // Add the matching files to source list this.sources = this.sources.Union(matchingFiles).ToList(); diff --git a/src/vstest.console/CommandLine/TestSourceException.cs b/src/vstest.console/CommandLine/TestSourceException.cs index 0cb6903b17..05f5e734f2 100644 --- a/src/vstest.console/CommandLine/TestSourceException.cs +++ b/src/vstest.console/CommandLine/TestSourceException.cs @@ -25,7 +25,17 @@ public TestSourceException() /// /// Message for the exception. public TestSourceException(string message) - : base(message) + : this(message, innerException: null) + { + } + + /// + /// Initializes with the message and innerException. + /// + /// Message for the exception. + /// The exception that is the cause of the current exception, or a null reference. + public TestSourceException(string message, Exception innerException) + : base(message, innerException) { } From 95173ba60bb528eddf1354d261e6793ed8d98726 Mon Sep 17 00:00:00 2001 From: Pavel Horak <22235234+pavelhorak@users.noreply.github.com> Date: Wed, 27 Jan 2021 16:06:34 +0100 Subject: [PATCH 42/46] Update AzureDevOps.yml --- .github/workflows/AzureDevOps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/AzureDevOps.yml b/.github/workflows/AzureDevOps.yml index d19baa94f3..2622b9f5ad 100644 --- a/.github/workflows/AzureDevOps.yml +++ b/.github/workflows/AzureDevOps.yml @@ -17,7 +17,7 @@ jobs: ado_organization: "${{ secrets.ADO_ORGANIZATION }}" ado_project: "${{ secrets.ADO_PROJECT }}" ado_area_path: "${{ secrets.ADO_AREA_PATH }}" - ado_iteration_path: "${{ secrets.ADO_ITERATION_PATH }}" + ado_iteration_path: "@CurrentIteration('[DevDiv]\\.NET DevExp Prague')" # ${{ secrets.ADO_ITERATION_PATH }}" ado_wit: "User Story" ado_new_state: "Committed" ado_active_state: "In Progress" From 49bee46c8ad3a5ea07ed174798c004d62f6e368a Mon Sep 17 00:00:00 2001 From: Pavel Horak <22235234+pavelhorak@users.noreply.github.com> Date: Wed, 27 Jan 2021 16:10:05 +0100 Subject: [PATCH 43/46] Update AzureDevOps.yml --- .github/workflows/AzureDevOps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/AzureDevOps.yml b/.github/workflows/AzureDevOps.yml index 2622b9f5ad..43b7bfde40 100644 --- a/.github/workflows/AzureDevOps.yml +++ b/.github/workflows/AzureDevOps.yml @@ -17,7 +17,7 @@ jobs: ado_organization: "${{ secrets.ADO_ORGANIZATION }}" ado_project: "${{ secrets.ADO_PROJECT }}" ado_area_path: "${{ secrets.ADO_AREA_PATH }}" - ado_iteration_path: "@CurrentIteration('[DevDiv]\\.NET DevExp Prague')" # ${{ secrets.ADO_ITERATION_PATH }}" + ado_iteration_path: ${{ secrets.ADO_ITERATION_PATH }}" # this doesn't work: "@CurrentIteration('[DevDiv]\\.NET DevExp Prague')" ado_wit: "User Story" ado_new_state: "Committed" ado_active_state: "In Progress" From 9bcf50930d4c2126cd9949110c88dd13471dbc06 Mon Sep 17 00:00:00 2001 From: Medeni Baykal <433724+Haplois@users.noreply.github.com> Date: Wed, 27 Jan 2021 17:15:40 +0100 Subject: [PATCH 44/46] Move FQN related code into a separate NuGet package (#2714) * Removed ManagedNameUtilities from ObjectModel in order to restore compatibility with older versions. * Added `Microsoft.TestPlatform.AdapterUtilities`. * Added `net20` and `net35` support to the code. --- .gitignore | 1 + TestPlatform.sln | 51 +++- scripts/build.ps1 | 37 ++- scripts/build.sh | 33 +-- scripts/verify-nupkgs.ps1 | 1 + .../Helpers/ReflectionHelpers.MethodBase.cs} | 10 +- .../Helpers/ReflectionHelpers.Type.cs} | 8 +- .../Helpers/ReflectionHelpers.cs} | 8 +- .../ManagedNameUtilities/Contants.cs | 14 + .../InvalidManagedNameException.cs | 2 +- .../ManagedNameHelper.Reflection.cs | 167 ++++++++--- .../ManagedNameUtilities/ManagedNameParser.cs | 225 +++++++++++++++ ...osoft.TestPlatform.AdapterUtilities.csproj | 51 ++++ .../Resources/Resources.Designer.cs} | 121 ++++---- .../Resources/Resources.resx} | 6 + .../Resources/xlf/Resources.cs.xlf} | 9 +- .../Resources/xlf/Resources.de.xlf} | 9 +- .../Resources/xlf/Resources.es.xlf} | 9 +- .../Resources/xlf/Resources.fr.xlf} | 9 +- .../Resources/xlf/Resources.it.xlf} | 9 +- .../Resources/xlf/Resources.ja.xlf} | 9 +- .../Resources/xlf/Resources.ko.xlf} | 9 +- .../Resources/xlf/Resources.pl.xlf} | 9 +- .../Resources/xlf/Resources.pt-BR.xlf} | 9 +- .../Resources/xlf/Resources.ru.xlf} | 9 +- .../Resources/xlf/Resources.tr.xlf} | 9 +- .../Resources/xlf/Resources.xlf} | 9 +- .../Resources/xlf/Resources.zh-Hans.xlf} | 9 +- .../Resources/xlf/Resources.zh-Hant.xlf} | 9 +- .../Resources/Resources.resx | 6 - .../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 - ...rosoft.TestPlatform.CrossPlatEngine.csproj | 2 +- ...tform.Extensions.BlameDataCollector.csproj | 4 +- .../ManagedNameUtilities/ManagedNameParser.cs | 188 ------------- .../Microsoft.TestPlatform.ObjectModel.csproj | 13 - .../TestCase.cs | 201 +++---------- ...osoft.TestPlatform.AdapterUtilities.nuspec | 51 ++++ .../FindMethodExtensions.cs | 2 +- .../ManagedNameParserTests.cs | 14 +- .../ManagedNameRoundTripTests.cs | 266 +++++++++--------- ...latform.AdapterUtilities.UnitTests.csproj} | 12 +- .../Program.cs | 2 +- .../TestClasses.cs | 0 .../TestResultSerializationTests.cs | 2 +- 57 files changed, 945 insertions(+), 777 deletions(-) rename src/{Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.MethodBase.cs => Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.MethodBase.cs} (84%) rename src/{Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.Type.cs => Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.Type.cs} (69%) rename src/{Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.cs => Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.cs} (68%) create mode 100644 src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/Contants.cs rename src/{Microsoft.TestPlatform.ObjectModel => Microsoft.TestPlatform.AdapterUtilities}/ManagedNameUtilities/InvalidManagedNameException.cs (80%) rename src/{Microsoft.TestPlatform.ObjectModel => Microsoft.TestPlatform.AdapterUtilities}/ManagedNameUtilities/ManagedNameHelper.Reflection.cs (58%) create mode 100644 src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameParser.cs create mode 100644 src/Microsoft.TestPlatform.AdapterUtilities/Microsoft.TestPlatform.AdapterUtilities.csproj rename src/{Microsoft.TestPlatform.ObjectModel/Resources/ManagedNameMessages.Designer.cs => Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.Designer.cs} (57%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/ManagedNameMessages.resx => Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.resx} (95%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.cs.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.cs.xlf} (81%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.de.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.de.xlf} (81%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.es.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.es.xlf} (82%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.fr.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.fr.xlf} (81%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.it.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.it.xlf} (82%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ja.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ja.xlf} (81%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ko.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ko.xlf} (81%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.pl.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pl.xlf} (81%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.pt-BR.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pt-BR.xlf} (81%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ru.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ru.xlf} (83%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.tr.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.tr.xlf} (82%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.xlf} (74%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.zh-Hans.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hans.xlf} (81%) rename src/{Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.zh-Hant.xlf => Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hant.xlf} (81%) delete mode 100644 src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/ManagedNameParser.cs create mode 100644 src/package/nuspec/Microsoft.TestPlatform.AdapterUtilities.nuspec rename test/{Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests => Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities}/FindMethodExtensions.cs (97%) rename test/{Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests => Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities}/ManagedNameParserTests.cs (82%) rename test/{Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests => Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities}/ManagedNameRoundTripTests.cs (80%) rename test/{Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests.csproj => Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj} (81%) rename test/{Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests => Microsoft.TestPlatform.AdapterUtilities.UnitTests}/Program.cs (78%) rename test/{Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests => Microsoft.TestPlatform.AdapterUtilities.UnitTests}/TestClasses.cs (100%) diff --git a/.gitignore b/.gitignore index 9523d94f87..845632e36a 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ build*.log build*.wrn build*.err *.binlog +*.svclog # MSTest test Results [Tt]est[Rr]esult*/ diff --git a/TestPlatform.sln b/TestPlatform.sln index 9d14b72dc8..321f401295 100644 --- a/TestPlatform.sln +++ b/TestPlatform.sln @@ -65,6 +65,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vstest.console.UnitTests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests", "test\Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests\Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests.csproj", "{BFF7714C-E5A3-4EEB-B04B-5FA47F29AD03}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "perf", "perf", "{0D4DF78D-7E5F-4516-B19F-E6AA71A1DBF4}" + ProjectSection(SolutionItems) = preProject + scripts\perf\perf.ps1 = scripts\perf\perf.ps1 + scripts\perf\perfconfig.csv = scripts\perf\perfconfig.csv + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{DED1590A-ED25-413B-8590-006A4DD5B2FD}" + ProjectSection(SolutionItems) = preProject + scripts\build\TestPlatform.Dependencies.props = scripts\build\TestPlatform.Dependencies.props + scripts\build\TestPlatform.Localization.targets = scripts\build\TestPlatform.Localization.targets + scripts\build\TestPlatform.Settings.targets = scripts\build\TestPlatform.Settings.targets + scripts\build\TestPlatform.targets = scripts\build\TestPlatform.targets + EndProjectSection +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330}" ProjectSection(SolutionItems) = preProject scripts\build.ps1 = scripts\build.ps1 @@ -73,6 +87,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{EE49 scripts\stylecop.test.ruleset = scripts\stylecop.test.ruleset scripts\test.ps1 = scripts\test.ps1 scripts\verify-sign.ps1 = scripts\verify-sign.ps1 + scripts\verify-nupkgs.ps1 = scripts\verify-nupkgs.ps1 + scripts\PortableToFullPdb.ps1 = scripts\PortableToFullPdb.ps1 + scripts\vsts-prebuild.ps1 = scripts\vsts-prebuild.ps1 + scripts\write-release-notes.ps1 = scripts\write-release-notes.ps1 + scripts\build.sh = scripts\build.sh + scripts\test.sh = scripts\test.sh EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E344E0A2-7715-4C7F-BAF7-D64EA94CB19B}" @@ -100,14 +120,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "datacollector.PlatformTests EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platform", "Platform", "{7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{DED1590A-ED25-413B-8590-006A4DD5B2FD}" - ProjectSection(SolutionItems) = preProject - scripts\build\TestPlatform.Dependencies.props = scripts\build\TestPlatform.Dependencies.props - scripts\build\TestPlatform.Localization.targets = scripts\build\TestPlatform.Localization.targets - scripts\build\TestPlatform.Settings.targets = scripts\build\TestPlatform.Settings.targets - scripts\build\TestPlatform.targets = scripts\build\TestPlatform.targets - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "package", "src\package\package\package.csproj", "{E141A226-CC0A-4F26-BD17-4AE427D81C3B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platform", "Platform", "{376C19DE-31E2-4FF6-88FC-0D0D6233C999}" @@ -132,12 +144,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataCollectors", "DataColle EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests", "test\DataCollectors\Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests\Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests.csproj", "{21DB138B-85B7-479E-91FE-01E0F972EC56}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "perf", "perf", "{0D4DF78D-7E5F-4516-B19F-E6AA71A1DBF4}" - ProjectSection(SolutionItems) = preProject - scripts\perf\perf.ps1 = scripts\perf\perf.ps1 - scripts\perf\perfconfig.csv = scripts\perf\perfconfig.csv - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vstest.console.PlatformTests", "test\vstest.console.PlatformTests\vstest.console.PlatformTests.csproj", "{8C068694-23A2-47A2-A0DD-DB82D0AF0142}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Common.PlatformTests", "test\Microsoft.TestPlatform.Common.PlatformTests\Microsoft.TestPlatform.Common.PlatformTests.csproj", "{24C7683D-2607-4901-B8EB-83A57E49E93D}" @@ -152,7 +158,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Exte EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "coverlet.collector", "test\coverlet.collector\coverlet.collector.csproj", "{074F5BD6-DC05-460B-B78F-044D125FD787}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests", "test\Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests\Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests.csproj", "{DCD0C39E-C78C-4A44-B0BD-7325254A2E97}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.AdapterUtilities.UnitTests", "test\Microsoft.TestPlatform.AdapterUtilities.UnitTests\Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj", "{DCD0C39E-C78C-4A44-B0BD-7325254A2E97}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.AdapterUtilities", "src\Microsoft.TestPlatform.AdapterUtilities\Microsoft.TestPlatform.AdapterUtilities.csproj", "{2DE99835-A3A3-4922-82AD-6D10D284816D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -764,6 +772,18 @@ Global {DCD0C39E-C78C-4A44-B0BD-7325254A2E97}.Release|x64.Build.0 = Release|Any CPU {DCD0C39E-C78C-4A44-B0BD-7325254A2E97}.Release|x86.ActiveCfg = Release|Any CPU {DCD0C39E-C78C-4A44-B0BD-7325254A2E97}.Release|x86.Build.0 = Release|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Debug|x64.ActiveCfg = Debug|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Debug|x64.Build.0 = Debug|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Debug|x86.ActiveCfg = Debug|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Debug|x86.Build.0 = Debug|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Release|Any CPU.Build.0 = Release|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Release|x64.ActiveCfg = Release|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Release|x64.Build.0 = Release|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Release|x86.ActiveCfg = Release|Any CPU + {2DE99835-A3A3-4922-82AD-6D10D284816D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -831,6 +851,7 @@ Global {41248B96-6E15-4E5E-A78F-859897676814} = {020E15EA-731F-4667-95AF-226671E0C3AE} {074F5BD6-DC05-460B-B78F-044D125FD787} = {D9A30E32-D466-4EC5-B4F2-62E17562279B} {DCD0C39E-C78C-4A44-B0BD-7325254A2E97} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} + {2DE99835-A3A3-4922-82AD-6D10D284816D} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0541B30C-FF51-4E28-B172-83F5F3934BCD} diff --git a/scripts/build.ps1 b/scripts/build.ps1 index fb6ced6651..9a6f5a19e8 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -334,6 +334,9 @@ function Publish-Package $dotnetExe = Get-DotNetPath $fullCLRPackage451Dir = Get-FullCLRPackageDirectory $fullCLRPackage45Dir = Get-FullCLRPackageDirectory45 + $uap100PackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\$TPB_TargetFrameworkUap100"); + $net20PackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\net20"); + $net35PackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\net35"); $netstandard10PackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\$TPB_TargetFrameworkNS10"); $netstandard13PackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\$TPB_TargetFrameworkNS13"); $netstandard20PackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\$TPB_TargetFrameworkNS20"); @@ -478,6 +481,17 @@ function Publish-Package $TPB_TargetFrameworkUap100 = $testhostUapPackageDir # uap10.0 } + ################################################################################ + # Publish Microsoft.TestPlatform.AdapterUtilities + Copy-Bulk -root (Join-Path $env:TP_ROOT_DIR "src\Microsoft.TestPlatform.AdapterUtilities\bin\$TPB_Configuration") ` + -files @{ + # "net20" = $net20PackageDir # net20 \ net20, and net35 isn't supported by the Test Platform + # "net35" = $net35PackageDir # net35 / but this package supports, so adding targets. + $TPB_TargetFrameworkNS10 = $netstandard10PackageDir # netstandard1_0 + $TPB_TargetFrameworkNS20 = $netstandard20PackageDir # netstandard2_0 + $TPB_TargetFrameworkUap100 = $uap100PackageDir # uap10.0 + } + ################################################################################ # Publish msdia $comComponentsDirectory = Join-Path $env:TP_PACKAGES_DIR "Microsoft.Internal.Dia\14.0.0\contentFiles\any\any\ComComponents" @@ -805,16 +819,19 @@ function Create-NugetPackages $tpNuspecDir = Join-Path $env:TP_PACKAGE_PROJ_DIR "nuspec" # Copy over the nuspecs to the staging directory - $nuspecFiles = @("TestPlatform.TranslationLayer.nuspec", - "TestPlatform.ObjectModel.nuspec", - "TestPlatform.TestHost.nuspec", - "TestPlatform.CLI.nuspec", - "TestPlatform.Build.nuspec", - "TestPlatform.Extensions.TrxLogger.nuspec", - "Microsoft.NET.Test.Sdk.nuspec", - "Microsoft.TestPlatform.nuspec", - "Microsoft.TestPlatform.Portable.nuspec", - "Microsoft.CodeCoverage.nuspec") + $nuspecFiles = @( + "Microsoft.CodeCoverage.nuspec", + "Microsoft.NET.Test.Sdk.nuspec", + "Microsoft.TestPlatform.AdapterUtilities.nuspec", + "Microsoft.TestPlatform.nuspec", + "Microsoft.TestPlatform.Portable.nuspec", + "TestPlatform.Build.nuspec", + "TestPlatform.CLI.nuspec", + "TestPlatform.Extensions.TrxLogger.nuspec", + "TestPlatform.ObjectModel.nuspec", + "TestPlatform.TestHost.nuspec", + "TestPlatform.TranslationLayer.nuspec" + ) $targetFiles = @("Microsoft.CodeCoverage.targets") $propFiles = @("Microsoft.NET.Test.Sdk.props", "Microsoft.CodeCoverage.props") diff --git a/scripts/build.sh b/scripts/build.sh index 6325f174ac..e06fb9721b 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -215,18 +215,18 @@ function restore_package() log "restore_package: Start restoring packages to $TP_PACKAGES_DIR." local start=$SECONDS - if [[ $TP_USE_REPO_API = 0 ]]; then - log ".. .. Restore: Source: $TP_ROOT_DIR/src/package/external/external.csproj" - $dotnet restore $TP_ROOT_DIR/src/package/external/external.csproj --packages $TP_PACKAGES_DIR -v:minimal -warnaserror -p:Version=$TPB_Version || failed=true - else - log ".. .. Restore: Source: $TP_ROOT_DIR/src/package/external/external_BuildFromSource.csproj" - $dotnet restore $TP_ROOT_DIR/src/package/external/external.csproj --packages $TP_PACKAGES_DIR -v:minimal -warnaserror -p:Version=$TPB_Version -p:DotNetBuildFromSource=true || failed=true - fi - - if [ "$failed" = true ]; then - error "Failed to restore packages." - return 2 - fi + if [[ $TP_USE_REPO_API = 0 ]]; then + log ".. .. Restore: Source: $TP_ROOT_DIR/src/package/external/external.csproj" + $dotnet restore $TP_ROOT_DIR/src/package/external/external.csproj --packages $TP_PACKAGES_DIR -v:minimal -warnaserror -p:Version=$TPB_Version || failed=true + else + log ".. .. Restore: Source: $TP_ROOT_DIR/src/package/external/external_BuildFromSource.csproj" + $dotnet restore $TP_ROOT_DIR/src/package/external/external.csproj --packages $TP_PACKAGES_DIR -v:minimal -warnaserror -p:Version=$TPB_Version -p:DotNetBuildFromSource=true || failed=true + fi + + if [ "$failed" = true ]; then + error "Failed to restore packages." + return 2 + fi log "restore_package: Complete. Elapsed $(( SECONDS - start ))s." } @@ -245,9 +245,9 @@ function invoke_build() if [ -z "$PROJECT_NAME_PATTERNS" ] then if [[ $TP_USE_REPO_API = 0 ]]; then - $dotnet build $TPB_Solution --configuration $TPB_Configuration -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild || failed=true + $dotnet build $TPB_Solution --configuration $TPB_Configuration -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild -bl:TestPlatform.binlog || failed=true else - $dotnet build $TPB_Build_From_Source_Solution --configuration $TPB_Configuration -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild -p:DotNetBuildFromSource=true || failed=true + $dotnet build $TPB_Build_From_Source_Solution --configuration $TPB_Configuration -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild -p:DotNetBuildFromSource=true -bl:TestPlatform.binlog || failed=true fi else find . -name "$PROJECT_NAME_PATTERNS" | xargs -L 1 $dotnet build --configuration $TPB_Configuration -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild @@ -370,8 +370,9 @@ function create_package() packageOutputDir="$TP_OUT_DIR/$TPB_Configuration/packages" mkdir -p $packageOutputDir - nuspecFiles=("TestPlatform.TranslationLayer.nuspec" "TestPlatform.ObjectModel.nuspec" "TestPlatform.TestHost.nuspec"\ - "Microsoft.TestPlatform.nuspec" "Microsoft.TestPlatform.Portable.nuspec" "TestPlatform.CLI.nuspec" "TestPlatform.Build.nuspec" "Microsoft.NET.Test.Sdk.nuspec") + nuspecFiles=("TestPlatform.TranslationLayer.nuspec" "TestPlatform.ObjectModel.nuspec" "TestPlatform.ObjectModel.nuspec" "TestPlatform.TestHost.nuspec"\ + "Microsoft.TestPlatform.nuspec" "Microsoft.TestPlatform.Portable.nuspec" "TestPlatform.CLI.nuspec" "TestPlatform.Build.nuspec" "Microsoft.NET.Test.Sdk.nuspec"\ + "Microsoft.CodeCoverage.nuspec" "Microsoft.TestPlatform.AdapterUtilities.nuspec" "TestPlatform.Extensions.TrxLogger.nuspec") projectFiles=("Microsoft.TestPlatform.CLI.csproj" "Microsoft.TestPlatform.Build.csproj") binDir="$TP_ROOT_DIR/bin/packages" diff --git a/scripts/verify-nupkgs.ps1 b/scripts/verify-nupkgs.ps1 index 0d0509c070..c660deb065 100644 --- a/scripts/verify-nupkgs.ps1 +++ b/scripts/verify-nupkgs.ps1 @@ -19,6 +19,7 @@ function Verify-Nuget-Packages($packageDirectory, $version) "Microsoft.TestPlatform.CLI" = 380; "Microsoft.TestPlatform.Extensions.TrxLogger" = 34; "Microsoft.TestPlatform.ObjectModel" = 179; + "Microsoft.TestPlatform.AdapterUtilities" = 47; "Microsoft.TestPlatform.Portable" = 569; "Microsoft.TestPlatform.TestHost" = 213; "Microsoft.TestPlatform.TranslationLayer" = 122; diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.MethodBase.cs b/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.MethodBase.cs similarity index 84% rename from src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.MethodBase.cs rename to src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.MethodBase.cs index 5e20bad1bd..0eaad1f4ed 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.MethodBase.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.MethodBase.cs @@ -1,12 +1,12 @@ // 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.PlatformAbstractions.Extensions +namespace Microsoft.TestPlatform.AdapterUtilities.Helpers { using System; using System.Reflection; - public static partial class ReflectionExtensions + internal static partial class ReflectionHelpers { #if NETSTANDARD1_0 || NETSTANDARD1_3 || WINDOWS_UWP private static readonly Type methodBase = typeof(MethodBase); @@ -20,7 +20,7 @@ public static partial class ReflectionExtensions private static readonly PropertyInfo methodHandleProperty = methodBase.GetRuntimeProperty(MethodHandlePropertyName); #endif - public static bool IsMethod(this MethodBase method) + internal static bool IsMethod(MethodBase method) { #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !WINDOWS_UWP return method.MemberType == MemberTypes.Method; @@ -31,7 +31,7 @@ public static bool IsMethod(this MethodBase method) #endif } - public static Type GetReflectedType(this MethodBase method) + internal static Type GetReflectedType(MethodBase method) { #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !WINDOWS_UWP return method.ReflectedType; @@ -42,7 +42,7 @@ public static Type GetReflectedType(this MethodBase method) #endif } - public static RuntimeMethodHandle GetMethodHandle(this MethodBase method) + internal static RuntimeMethodHandle GetMethodHandle(MethodBase method) { #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !WINDOWS_UWP return method.MethodHandle; diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.Type.cs b/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.Type.cs similarity index 69% rename from src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.Type.cs rename to src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.Type.cs index 65670afd06..d8e8d23b5c 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.Type.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.Type.cs @@ -1,14 +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. -namespace Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Extensions +namespace Microsoft.TestPlatform.AdapterUtilities.Helpers { using System; using System.Reflection; - public static partial class ReflectionExtensions + internal static partial class ReflectionHelpers { - public static bool IsGenericType(this Type type) + internal static bool IsGenericType(Type type) { #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !WINDOWS_UWP return type.IsGenericType; @@ -17,7 +17,7 @@ public static bool IsGenericType(this Type type) #endif } - public static MethodBase GetDeclaringMethod(this Type type) + internal static MethodBase GetDeclaringMethod(Type type) { #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !WINDOWS_UWP return type.DeclaringMethod; diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.cs b/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.cs similarity index 68% rename from src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.cs rename to src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.cs index 010567f0eb..2b30b8c129 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Extensions/ReflectionExtensions.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.cs @@ -1,15 +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. -namespace Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Extensions +namespace Microsoft.TestPlatform.AdapterUtilities.Helpers { - using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Resources; + using Microsoft.TestPlatform.AdapterUtilities.Resources; using System; - public static partial class ReflectionExtensions + internal static partial class ReflectionHelpers { - private static void AssertSupport(T obj, string methodName, string className) + private static void AssertSupport(T obj, string methodName, string className) where T : class { if (obj == null) diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/Contants.cs b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/Contants.cs new file mode 100644 index 0000000000..77b8c2c2bb --- /dev/null +++ b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/Contants.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. + +namespace Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities +{ + public static class Contants + { + public const string ManagedTypeLabel = "ManagedType"; + public const string ManagedMethodLabel = "ManagedMethod"; + + public const string ManagedTypePropertyId = "TestCase." + ManagedTypeLabel; + public const string ManagedMethodPropertyId = "TestCase." + ManagedMethodLabel; + } +} diff --git a/src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/InvalidManagedNameException.cs b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/InvalidManagedNameException.cs similarity index 80% rename from src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/InvalidManagedNameException.cs rename to src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/InvalidManagedNameException.cs index 4a1e2a3a1f..1899e65c96 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/InvalidManagedNameException.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/InvalidManagedNameException.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.VisualStudio.TestPlatform.ObjectModel.ManagedNameUtilities +namespace Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities { using System; diff --git a/src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/ManagedNameHelper.Reflection.cs b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs similarity index 58% rename from src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/ManagedNameHelper.Reflection.cs rename to src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs index b0d7727995..93a0defca5 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/ManagedNameHelper.Reflection.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs @@ -1,52 +1,65 @@ // 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.ObjectModel.ManagedNameUtilities +namespace Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities { - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Resources; - using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Extensions; + using Microsoft.TestPlatform.AdapterUtilities.Resources; + using Microsoft.TestPlatform.AdapterUtilities.Helpers; using System; using System.Globalization; - using System.Linq; using System.Reflection; using System.Text; +#if !NET20 + using System.Linq; +#endif + public static partial class ManagedNameHelper { /// - /// Gets fully qualified type and method name from given MethodBase instance. + /// Gets fully qualified managed type and method name from given instance. /// /// - /// A MethodBase instance to get fully qualified type and method name. + /// A instance to get fully qualified managed type and method name. /// - /// - /// When this method returns, contains the fully qualified type name of the . + /// + /// When this method returns, contains the fully qualified managed type name of the . /// This parameter is passed uninitialized; any value originally supplied in result will be overwritten. + /// The format is defined in the RFC. /// - /// - /// When this method returns, contains the fully qualified method name of the . + /// + /// When this method returns, contains the fully qualified managed method name of the . /// This parameter is passed uninitialized; any value originally supplied in result will be overwritten. + /// The format is defined in the RFC. /// - /// is null. - /// must describe a method. + /// + /// is null. + /// + /// + /// must describe a method. + /// /// /// Required functionality on is missing on the current platform. /// - public static void GetManagedName(MethodBase method, out string fullTypeName, out string fullMethodName) + /// + /// More information about and can be found in + /// the RFC. + /// + public static void GetManagedName(MethodBase method, out string managedTypeName, out string managedMethodName) { if (method == null) { throw new ArgumentNullException(nameof(method)); } - if (!method.IsMethod()) + if (!ReflectionHelpers.IsMethod(method)) { throw new NotSupportedException(nameof(method)); } - var semanticType = method.GetReflectedType(); - if (semanticType.IsGenericType()) + var semanticType = ReflectionHelpers.GetReflectedType(method); + if (ReflectionHelpers.IsGenericType(semanticType)) { // The type might have some of its generic parameters specified, so make // sure we are working with the open form of the generic type. @@ -56,7 +69,7 @@ public static void GetManagedName(MethodBase method, out string fullTypeName, ou // declaration. Here we use the method handle (basically metadata token) to create // a new method reference using the open form of the reflected type. The intent is // to strip all generic type parameters. - var methodHandle = method.GetMethodHandle(); + var methodHandle = ReflectionHelpers.GetMethodHandle(method); method = MethodBase.GetMethodFromHandle(methodHandle, semanticType.TypeHandle); } @@ -84,7 +97,7 @@ public static void GetManagedName(MethodBase method, out string fullTypeName, ou // Type Parameters var paramList = method.GetParameters(); - if (paramList.Any()) + if (paramList.Length != 0) { methodBuilder.Append('('); foreach (var p in paramList) @@ -96,40 +109,46 @@ public static void GetManagedName(MethodBase method, out string fullTypeName, ou methodBuilder[methodBuilder.Length - 1] = ')'; } - fullTypeName = typeBuilder.ToString(); - fullMethodName = methodBuilder.ToString(); + managedTypeName = typeBuilder.ToString(); + managedMethodName = methodBuilder.ToString(); } /// - /// Gets the object with the specified - /// and in the instance. + /// Gets the object with the specified + /// and in the instance. /// /// /// An instance to search in. /// - /// - /// The fully qualified name of the type. + /// + /// The fully qualified managed name of the type. + /// The format is defined in the RFC. /// - /// - /// The fully qualified name of the method. + /// + /// The fully qualified managed name of the method. + /// The format is defined in the RFC. /// /// /// A object that represents specified parameters, throws if null. /// /// - /// Values specified with and + /// Values specified with and /// does not correspond to a method in the instance, or malformed. /// - public static MethodBase GetManagedName(Assembly assembly, string fullTypeName, string fullMethodName) + /// + /// More information about and can be found in + /// the RFC. + /// + public static MethodBase GetMethod(Assembly assembly, string managedTypeName, string managedMethodName) { Type type; #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !WINDOWS_UWP - type = assembly.GetType(fullTypeName, throwOnError: false, ignoreCase: false); + type = assembly.GetType(managedTypeName, throwOnError: false, ignoreCase: false); #else try { - type = assembly.GetType(fullTypeName); + type = assembly.GetType(managedTypeName); } catch { @@ -139,20 +158,25 @@ public static MethodBase GetManagedName(Assembly assembly, string fullTypeName, if (type == null) { - string message = String.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorTypeNotFound, fullTypeName); + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorTypeNotFound, managedTypeName); throw new InvalidManagedNameException(message); } MethodInfo method = null; - ManagedNameParser.ParseMethodName(fullMethodName, out var methodName, out var methodArity, out var parameterTypes); + ManagedNameParser.ParseManagedMethodName(managedMethodName, out var methodName, out var methodArity, out var parameterTypes); +#if NET20 || NET35 + + if (!IsNullOrWhiteSpace(methodName)) +#else if (!string.IsNullOrWhiteSpace(methodName)) +#endif { method = FindMethod(type, methodName, methodArity, parameterTypes); } if (method == null) { - string message = String.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorMethodNotFound, methodName, fullTypeName); + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorMethodNotFound, methodName, managedTypeName); throw new InvalidManagedNameException(message); } @@ -190,12 +214,20 @@ bool filter(MemberInfo mbr, object param) return true; } + MemberInfo[] methods; + #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !WINDOWS_UWP var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; - var methods = type.FindMembers(MemberTypes.Method, bindingFlags, filter, null); - return (MethodInfo)methods.SingleOrDefault(); + methods = type.FindMembers(MemberTypes.Method, bindingFlags, filter, null); #else - return type.GetRuntimeMethods().Where(m => filter(m, null)).SingleOrDefault(); + methods = type.GetRuntimeMethods().Where(m => filter(m, null)).ToArray(); +#endif + + +#if NET20 + return (MethodInfo)SingleOrDefault(methods); +#else + return (MethodInfo)methods.SingleOrDefault(); #endif } @@ -213,7 +245,7 @@ private static void AppendTypeString(StringBuilder b, Type type, bool closedType } else if (type.IsGenericParameter) { - if (type.GetDeclaringMethod() != null) + if (ReflectionHelpers.GetDeclaringMethod(type) != null) { b.Append('!'); } @@ -254,7 +286,7 @@ private static void AppendGenericTypeParameters(StringBuilder b, Type type) genargs = type.GetTypeInfo().GenericTypeArguments; #endif - if (genargs.Any()) + if (genargs.Length != 0) { b.Append('<'); foreach (var argType in genargs) @@ -273,5 +305,64 @@ private static string TypeString(Type type, bool closedType) AppendTypeString(builder, type, closedType); return builder.ToString(); } + +#if NET20 + + // the method is mostly copied from + // https://github.com/dotnet/runtime/blob/c0840723b382bcfa67b35839af8572fcd38f1d13/src/libraries/System.Linq/src/System/Linq/Single.cs#L86 + public static TSource SingleOrDefault(System.Collections.Generic.IEnumerable source) + { + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (source is System.Collections.Generic.IList list) + { + switch (list.Count) + { + case 0: + return default; + case 1: + return list[0]; + } + } + else + { + using (System.Collections.Generic.IEnumerator e = source.GetEnumerator()) + { + if (!e.MoveNext()) + { + return default; + } + + TSource result = e.Current; + if (!e.MoveNext()) + { + return result; + } + } + } + + throw new InvalidOperationException("MoreThanOneElement"); + } +#endif + +#if NET20 || NET35 + public static bool IsNullOrWhiteSpace(string value) + { + if (value is null) return true; + + for (int i = 0; i < value.Length; i++) + { + if (!char.IsWhiteSpace(value[i])) + { + return false; + } + } + + return true; + } +#endif } } diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameParser.cs b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameParser.cs new file mode 100644 index 0000000000..bf707f74c8 --- /dev/null +++ b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameParser.cs @@ -0,0 +1,225 @@ +// 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.AdapterUtilities.ManagedNameUtilities +{ + using Microsoft.TestPlatform.AdapterUtilities.Resources; + + using System.Collections.Generic; + using System.Diagnostics; + using System.Globalization; + + public class ManagedNameParser + { + /// + /// Parses a given fully qualified managed type name into its namespace and type name. + /// + /// + /// The fully qualified managed type name to parse. + /// The format is defined in the RFC. + /// + /// + /// When this method returns, contains the parsed namespace name of the . + /// This parameter is passed uninitialized; any value originally supplied in result will be overwritten. + /// + /// + /// When this method returns, contains the parsed type name of the . + /// This parameter is passed uninitialized; any value originally supplied in result will be overwritten. + /// + public static void ParseManagedTypeName(string managedTypeName, out string namespaceName, out string typeName) + { + int pos = managedTypeName.LastIndexOf('.'); + if (pos == -1) + { + namespaceName = string.Empty; + typeName = managedTypeName; + } + else + { + namespaceName = managedTypeName.Substring(0, pos); + typeName = managedTypeName.Substring(pos + 1); + } + } + + /// + /// Parses a given fully qualified managed method name into its name, arity and parameter types. + /// + /// + /// The fully qualified managed method name to parse. + /// The format is defined in the RFC. + /// + /// + /// When this method returns, contains the parsed method name of the . + /// This parameter is passed uninitialized; any value originally supplied in result will be overwritten. + /// + /// + /// When this method returns, contains the parsed arity of the . + /// This parameter is passed uninitialized; any value originally supplied in result will be overwritten. + /// + /// + /// When this method returns, contains the parsed parameter types of the . + /// If there are no parameter types in , is set to null. + /// This parameter is passed uninitialized; any value originally supplied in result will be overwritten. + /// + /// + /// Thrown if contains spaces, incomplete, or the arity isn't numeric. + /// + public static void ParseManagedMethodName(string managedMethodName, out string methodName, out int arity, out string[] parameterTypes) + { + int pos = ParseMethodName(managedMethodName, 0, out methodName, out arity); + pos = ParseParameterTypeList(managedMethodName, pos, out parameterTypes); + if (pos != managedMethodName.Length) + { + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorUnexpectedCharactersAtEnd, pos); + throw new InvalidManagedNameException(message); + } + } + + private static string Capture(string managedMethodName, int start, int end) + => managedMethodName.Substring(start, end - start); + + private static int ParseMethodName(string managedMethodName, int start, out string methodName, out int arity) + { + int i = start; + for (; i < managedMethodName.Length; i++) + { + switch (managedMethodName[i]) + { + case var w when char.IsWhiteSpace(w): + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorWhitespaceNotValid, i); + throw new InvalidManagedNameException(message); + case '`': + methodName = Capture(managedMethodName, start, i); + return ParseArity(managedMethodName, i, out arity); + case '(': + methodName = Capture(managedMethodName, start, i); + arity = 0; + return i; + } + } + methodName = Capture(managedMethodName, start, i); + arity = 0; + return i; + } + + // parse arity in the form `nn where nn is an integer value. + private static int ParseArity(string managedMethodName, int start, out int arity) + { + arity = 0; + Debug.Assert(managedMethodName[start] == '`'); + + int i = start + 1; // skip initial '`' char + for (; i < managedMethodName.Length; i++) + { + if (managedMethodName[i] == '(') break; + } + if (!int.TryParse(Capture(managedMethodName, start + 1, i), out arity)) + { + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorMethodArityMustBeNumeric); + throw new InvalidManagedNameException(message); + } + return i; + } + + private static int ParseParameterTypeList(string managedMethodName, int start, out string[] parameterTypes) + { + parameterTypes = null; + if (start == managedMethodName.Length) + { + return start; + } + Debug.Assert(managedMethodName[start] == '('); + + var types = new List(); + + int i = start + 1; // skip initial '(' char + for (; i < managedMethodName.Length; i++) + { + switch (managedMethodName[i]) + { + case ')': + if (types.Count != 0) + { + parameterTypes = types.ToArray(); + } + return i + 1; // consume right parens + case ',': + break; + default: + i = ParseParameterType(managedMethodName, i, out var parameterType); + types.Add(parameterType); + break; + } + } + + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorIncompleteManagedName); + throw new InvalidManagedNameException(message); + } + + private static int ParseParameterType(string managedMethodName, int start, out string parameterType) + { + parameterType = string.Empty; + + int i = start; + for (; i < managedMethodName.Length; i++) + { + switch (managedMethodName[i]) + { + case '<': + i = ParseGenericBrackets(managedMethodName, i + 1); + break; + case '[': + i = ParseArrayBrackets(managedMethodName, i + 1); + break; + case ',': + case ')': + parameterType = Capture(managedMethodName, start, i); + return i - 1; + case var w when char.IsWhiteSpace(w): + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorWhitespaceNotValid, i); + throw new InvalidManagedNameException(message); + } + } + return i; + } + + private static int ParseArrayBrackets(string managedMethodName, int start) + { + for (int i = start; i < managedMethodName.Length; i++) + { + switch (managedMethodName[i]) + { + case ']': + return i; + case var w when char.IsWhiteSpace(w): + string msg = string.Format(CultureInfo.CurrentCulture, Resources.ErrorWhitespaceNotValid, i); + throw new InvalidManagedNameException(msg); + } + } + + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorIncompleteManagedName); + throw new InvalidManagedNameException(message); + } + + private static int ParseGenericBrackets(string managedMethodName, int start) + { + for (int i = start; i < managedMethodName.Length; i++) + { + switch (managedMethodName[i]) + { + case '<': + i = ParseGenericBrackets(managedMethodName, i + 1); + break; + case '>': + return i; + case var w when char.IsWhiteSpace(w): + string msg = string.Format(CultureInfo.CurrentCulture, Resources.ErrorWhitespaceNotValid, i); + throw new InvalidManagedNameException(msg); + } + } + + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorIncompleteManagedName); + throw new InvalidManagedNameException(message); + } + } +} diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Microsoft.TestPlatform.AdapterUtilities.csproj b/src/Microsoft.TestPlatform.AdapterUtilities/Microsoft.TestPlatform.AdapterUtilities.csproj new file mode 100644 index 0000000000..aae96bd1d3 --- /dev/null +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Microsoft.TestPlatform.AdapterUtilities.csproj @@ -0,0 +1,51 @@ + + + ..\..\ + + + + + netstandard1.0;netstandard2.0 + $(TargetFrameworks);uap10.0 + true + + Microsoft.TestPlatform.AdapterUtilities + Microsoft.TestPlatform.AdapterUtilities + + + + false + UAP,Version=v10.0 + UAP + 10.0.14393.0 + 10.0.10240.0 + .NETPortable + v4.5 + $(DefineConstants);WINDOWS_UWP + + + .NETFramework + v4.5.1 + + + + + + + + + + + + + diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/ManagedNameMessages.Designer.cs b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.Designer.cs similarity index 57% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/ManagedNameMessages.Designer.cs rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.Designer.cs index 266ad299d1..19827c698e 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/ManagedNameMessages.Designer.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.Designer.cs @@ -1,118 +1,135 @@ -//------------------------------------------------------------------------------ -// -// 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.VisualStudio.TestPlatform.ObjectModel.Resources { - using System; +namespace Microsoft.TestPlatform.AdapterUtilities.Resources +{ 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", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class ManagedNameMessages { - + 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 ManagedNameMessages() { + + 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.VisualStudio.TestPlatform.ObjectModel.Resources.ManagedNameMessages", typeof(ManagedNameMessages).GetTypeInfo().Assembly); + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if (object.ReferenceEquals(resourceMan, null)) + { +#if NET20 || NET35 + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.TestPlatform.AdapterUtilities.Resources.Resources", typeof(Resources).Assembly); +#else + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.TestPlatform.AdapterUtilities.Resources.Resources", typeof(Resources).GetTypeInfo().Assembly); +#endif 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 { + internal static global::System.Globalization.CultureInfo Culture + { + get + { return resourceCulture; } - set { + set + { resourceCulture = value; } } - + /// /// Looks up a localized string similar to ManagedName is incomplete. /// - internal static string ErrorIncompleteManagedName { - get { + internal static string ErrorIncompleteManagedName + { + get + { return ResourceManager.GetString("ErrorIncompleteManagedName", resourceCulture); } } - + /// /// Looks up a localized string similar to Method arity must be numeric. /// - internal static string ErrorMethodArityMustBeNumeric { - get { + internal static string ErrorMethodArityMustBeNumeric + { + get + { return ResourceManager.GetString("ErrorMethodArityMustBeNumeric", resourceCulture); } } - + /// /// Looks up a localized string similar to Method '{0}' not found on type '{1}'. /// - internal static string ErrorMethodNotFound { - get { + internal static string ErrorMethodNotFound + { + get + { return ResourceManager.GetString("ErrorMethodNotFound", resourceCulture); } } - + /// /// Looks up a localized string similar to Type '{0}' not found. /// - internal static string ErrorTypeNotFound { - get { + internal static string ErrorTypeNotFound + { + get + { return ResourceManager.GetString("ErrorTypeNotFound", resourceCulture); } } - + /// /// Looks up a localized string similar to Unexpected characters after the end of the ManagedName (pos: {0}). /// - internal static string ErrorUnexpectedCharactersAtEnd { - get { + internal static string ErrorUnexpectedCharactersAtEnd + { + get + { return ResourceManager.GetString("ErrorUnexpectedCharactersAtEnd", resourceCulture); } } - + /// /// Looks up a localized string similar to Whitespace is not valid in a ManagedName (pos: {0}). /// - internal static string ErrorWhitespaceNotValid { - get { + internal static string ErrorWhitespaceNotValid + { + get + { return ResourceManager.GetString("ErrorWhitespaceNotValid", resourceCulture); } } + + /// + /// Looks up a localized string similar to '{0}.{1}' is not implemented on this platform!. + /// + internal static string MethodNotImplementedOnPlatform + { + get + { + return ResourceManager.GetString("MethodNotImplementedOnPlatform", resourceCulture); + } + } } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/ManagedNameMessages.resx b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.resx similarity index 95% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/ManagedNameMessages.resx rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.resx index 1f24f6db76..da81725acf 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/ManagedNameMessages.resx +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.resx @@ -139,4 +139,10 @@ Whitespace is not valid in a ManagedName (pos: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.cs.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.cs.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.cs.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.cs.xlf index 269f9a2b0e..77e0cf29b0 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.cs.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.cs.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ V ManagedName se nepovoluje mezera (pozice: {0}). {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + Metoda {0}.{1} není na této platformě implementována. + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.de.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.de.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.de.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.de.xlf index 4f3c097da7..cc3be8f402 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.de.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.de.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ Leerzeichen sind in einem ManagedName unzulässig (Position: {0}). {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + "{0}.{1}" ist auf dieser Plattform nicht implementiert! + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.es.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.es.xlf similarity index 82% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.es.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.es.xlf index 39217c3624..111e6b9dd4 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.es.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.es.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ El espacio en blanco no es válido en un elemento ManagedName (posición: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + "{0}.{1}" no se ha implementado en esta plataforma. + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.fr.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.fr.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.fr.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.fr.xlf index b666af0782..13be1b762b 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.fr.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.fr.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ Les espaces blancs ne sont pas valides dans un ManagedName (pos. : {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}' n'est pas implémenté sur cette plateforme ! + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.it.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.it.xlf similarity index 82% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.it.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.it.xlf index cd33cbb7ea..1602378445 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.it.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.it.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ Gli spazi vuoti non sono validi in un elemento ManagedName (pos.: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}' non è implementato in questa piattaforma. + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ja.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ja.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ja.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ja.xlf index 7750e56011..2bc25ce3ae 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ja.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ja.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ ManagedName では空白は無効です (位置: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}' はこのプラットフォームに実装されていません。 + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ko.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ko.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ko.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ko.xlf index 98db842b50..2ef4e1cdc3 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ko.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ko.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ ManagedName에서 공백은 유효하지 않습니다(pos: {0}). {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}'이(가)이 플랫폼에서 구현되지 않았습니다. + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.pl.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pl.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.pl.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pl.xlf index 16f4f78d95..9f40119244 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.pl.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pl.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ Biały znak jest niedozwolony w wartości ManagedName (pozycja: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + Element „{0}.{1}” nie jest zaimplementowany na tej platformie. + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.pt-BR.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pt-BR.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.pt-BR.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pt-BR.xlf index a3cb0cedd0..6e08e8348c 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pt-BR.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ O espaço em branco não é válido em um ManagedName (posição: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}' não está implementado nesta plataforma. + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ru.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ru.xlf similarity index 83% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ru.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ru.xlf index 53b7d79398..98ab3c94da 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.ru.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ru.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ Пробел в ManagedName (позиция: {0}) не допускается. {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}' bu platformda uygulanmıyor! + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.tr.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.tr.xlf similarity index 82% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.tr.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.tr.xlf index b2b390c509..fb6cc464b2 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.tr.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.tr.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ ManagedName'de boşluk geçersiz (konum: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}' bu platformda uygulanmıyor! + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.xlf similarity index 74% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.xlf index 6b76894923..232d95bf2d 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -26,6 +26,13 @@ Whitespace is not valid in a ManagedName (pos: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}' is not implemented on this platform! + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.zh-Hans.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hans.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.zh-Hans.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hans.xlf index 628b1862f6..2a3e79c29d 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hans.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ ManagedName 中空白无效(位置: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + 未在此平台上实现 "{0}.{1}"! + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.zh-Hant.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hant.xlf similarity index 81% rename from src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.zh-Hant.xlf rename to src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hant.xlf index ad7b49f7b0..b722fc446f 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/ManagedNameMessages.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hant.xlf @@ -1,6 +1,6 @@  - + ManagedName is incomplete @@ -32,6 +32,13 @@ 空白字元在 ManagedName 中無效 (位置: {0}) {0} is the position of invalid whitespace + + '{0}.{1}' is not implemented on this platform! + '{0}.{1}' 未在此平台上實作! + '{className}.{methodName}' is not implemented on this platform! + +Example: 'System.Reflection.MethodBase' is not implemented on this platform! + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/Resources.resx b/src/Microsoft.TestPlatform.CoreUtilities/Resources/Resources.resx index 27a397f0d5..ba520ac0b1 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/Resources.resx +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/Resources.resx @@ -165,10 +165,4 @@ Error getting process name. - - '{0}.{1}' is not implemented on this platform! - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.cs.xlf index b02df0a203..d3fcf4893f 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.cs.xlf @@ -160,13 +160,6 @@ Hostitele {0} nešlo najít. Ujistěte se, jestli je {0} nainstalovaný na počítači a dostupný v cestě určené proměnnou prostředí PATH. - - '{0}.{1}' is not implemented on this platform! - Metoda {0}.{1} není na této platformě implementována. - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.de.xlf index 62e6c896ab..e56739c937 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.de.xlf @@ -160,13 +160,6 @@ Der Host "{0}" wurde nicht gefunden. Stellen Sie sicher, dass "{0}" auf dem Computer installiert und in der PATH-Umgebungsvariablen verfügbar ist. - - '{0}.{1}' is not implemented on this platform! - "{0}.{1}" ist auf dieser Plattform nicht implementiert! - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.es.xlf index cfc9211a5b..b428568d5f 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.es.xlf @@ -160,13 +160,6 @@ No se pudo encontrar el host "{0}". Asegúrese de que "{0}" está instalado en el equipo y está disponible en la variable de entorno PATH. - - '{0}.{1}' is not implemented on this platform! - "{0}.{1}" no se ha implementado en esta plataforma. - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.fr.xlf index b4d70ebe7f..776258dfeb 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.fr.xlf @@ -160,13 +160,6 @@ L'hôte '{0}' est introuvable. Vérifiez que '{0}' est installé sur la machine et qu'il est disponible dans la variable d'environnement PATH. - - '{0}.{1}' is not implemented on this platform! - '{0}.{1}' n'est pas implémenté sur cette plateforme ! - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.it.xlf index 4a9bd3636f..2a67405108 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.it.xlf @@ -160,13 +160,6 @@ L'host '{0}' non è stato trovato. Assicurarsi che '{0}' sia installato nel computer e che sia disponibile nella variabile di ambiente PATH. - - '{0}.{1}' is not implemented on this platform! - '{0}.{1}' non è implementato in questa piattaforma. - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ja.xlf index c76e744adb..f7540bc847 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ja.xlf @@ -160,13 +160,6 @@ '{0}' ホストが見つかりませんでした。'{0}' がコンピューターにインストールされており、PATH 環境変数で使用できることを確認してください。 - - '{0}.{1}' is not implemented on this platform! - '{0}.{1}' はこのプラットフォームに実装されていません。 - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ko.xlf index 36facccc77..045f1456c0 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ko.xlf @@ -160,13 +160,6 @@ ‘{0}’ 호스트를 찾을 수 없습니다. ‘{0}’이(가) 컴퓨터에 설치되어 있고 PATH 환경 변수에서 사용할 수 있는지 확인하세요. - - '{0}.{1}' is not implemented on this platform! - '{0}.{1}'이(가)이 플랫폼에서 구현되지 않았습니다. - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.pl.xlf index c1a12883ea..1a4f72c7c4 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.pl.xlf @@ -160,13 +160,6 @@ Nie można znaleźć hosta „{0}”. Upewnij się, że element „{0}” jest zainstalowany na maszynie i jest dostępny w zmiennej środowiskowej PATH. - - '{0}.{1}' is not implemented on this platform! - Element „{0}.{1}” nie jest zaimplementowany na tej platformie. - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.pt-BR.xlf index 73254f2b69..c1ca953991 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.pt-BR.xlf @@ -160,13 +160,6 @@ Não foi possível encontrar o host '{0}'. Verifique se o '{0}' está instalado no computador e está disponível na variável de ambiente PATH. - - '{0}.{1}' is not implemented on this platform! - '{0}.{1}' não está implementado nesta plataforma. - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ru.xlf index 40802900c1..439e58c02c 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.ru.xlf @@ -160,13 +160,6 @@ Не удалось найти хост "{0}". Убедитесь, что "{0}" установлен на компьютере и доступен в переменной среды PATH. - - '{0}.{1}' is not implemented on this platform! - Метод "{0}.{1}" не реализован на этой платформе. - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.tr.xlf index 9aeedcc6b3..e137c740bd 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.tr.xlf @@ -160,13 +160,6 @@ '{0}' konağı bulunamadı. '{0}' konağının makinede yüklü olduğundan ve PATH ortam değişkeninde bulunduğundan emin olun. - - '{0}.{1}' is not implemented on this platform! - '{0}.{1}' bu platformda uygulanmıyor! - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.xlf index f557a28547..615147279b 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.xlf @@ -67,13 +67,6 @@ Could not find {0}. Make sure that the dotnet is installed on the machine. - - '{0}.{1}' is not implemented on this platform! - '{0}.{1}' is not implemented on this platform! - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.zh-Hans.xlf index 1490343772..4d75b26690 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.zh-Hans.xlf @@ -160,13 +160,6 @@ 找不到“{0}”主机。请确保计算机上已安装“{0}”且位于 PATH 环境变量中。 - - '{0}.{1}' is not implemented on this platform! - 未在此平台上实现 "{0}.{1}"! - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.zh-Hant.xlf index 19fd67d30f..c46a781603 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.CoreUtilities/Resources/xlf/Resources.zh-Hant.xlf @@ -160,13 +160,6 @@ 找不到 '{0}' 主機。請確認 '{0}' 已安裝在機器上,而且可在 PATH 環境變數中使用。 - - '{0}.{1}' is not implemented on this platform! - '{0}.{1}' 未在此平台上實作! - '{className}.{methodName}' is not implemented on this platform! - -Example: 'System.Reflection.MethodBase' is not implemented on this platform! - \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Microsoft.TestPlatform.CrossPlatEngine.csproj b/src/Microsoft.TestPlatform.CrossPlatEngine/Microsoft.TestPlatform.CrossPlatEngine.csproj index f350f7fd32..72e7d1f777 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Microsoft.TestPlatform.CrossPlatEngine.csproj +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Microsoft.TestPlatform.CrossPlatEngine.csproj @@ -21,7 +21,7 @@ - + true 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 e88e26ab36..5ac9c65b5d 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/Microsoft.TestPlatform.Extensions.BlameDataCollector.csproj @@ -34,9 +34,7 @@ - - 0.2.0-preview.20419.2 - + diff --git a/src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/ManagedNameParser.cs b/src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/ManagedNameParser.cs deleted file mode 100644 index f83eab158c..0000000000 --- a/src/Microsoft.TestPlatform.ObjectModel/ManagedNameUtilities/ManagedNameParser.cs +++ /dev/null @@ -1,188 +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. - -namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.ManagedNameUtilities -{ - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Resources; - - using System.Collections.Generic; - using System.Diagnostics; - using System.Globalization; - using System.Linq; - - public class ManagedNameParser - { - internal static void ParseTypeName(string fullTypeName, out string namespaceName, out string typeName) - { - int pos = fullTypeName.LastIndexOf('.'); - if (pos == -1) - { - namespaceName = string.Empty; - typeName = fullTypeName; - } - else - { - namespaceName = fullTypeName.Substring(0, pos); - typeName = fullTypeName.Substring(pos + 1); - } - } - - internal static void ParseMethodName(string fullMethodName, out string methodName, out int arity, out string[] parameterTypes) - { - int pos = ParseMethodName(fullMethodName, 0, out methodName, out arity); - pos = ParseParameterTypeList(fullMethodName, pos, out parameterTypes); - if (pos != fullMethodName.Length) - { - string message = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorUnexpectedCharactersAtEnd, pos); - throw new InvalidManagedNameException(message); - } - } - - private static string Capture(string fullMethodName, int start, int end) - => fullMethodName.Substring(start, end - start); - - private static int ParseMethodName(string fullMethodName, int start, out string methodName, out int arity) - { - int i = start; - for (; i < fullMethodName.Length; i++) - { - switch (fullMethodName[i]) - { - case var w when char.IsWhiteSpace(w): - string message = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorWhitespaceNotValid, i); - throw new InvalidManagedNameException(message); - case '`': - methodName = Capture(fullMethodName, start, i); - return ParseArity(fullMethodName, i, out arity); - case '(': - methodName = Capture(fullMethodName, start, i); - arity = 0; - return i; - } - } - methodName = Capture(fullMethodName, start, i); - arity = 0; - return i; - } - - // parse arity in the form `nn where nn is an integer value. - private static int ParseArity(string fullMethodName, int start, out int arity) - { - arity = 0; - Debug.Assert(fullMethodName[start] == '`'); - - int i = start + 1; // skip initial '`' char - for (; i < fullMethodName.Length; i++) - { - if (fullMethodName[i] == '(') break; - } - if (!int.TryParse(Capture(fullMethodName, start + 1, i), out arity)) - { - string message = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorMethodArityMustBeNumeric); - throw new InvalidManagedNameException(message); - } - return i; - } - - private static int ParseParameterTypeList(string fullMethodName, int start, out string[] parameterTypes) - { - parameterTypes = null; - if (start == fullMethodName.Length) - { - return start; - } - Debug.Assert(fullMethodName[start] == '('); - - var types = new List(); - - int i = start + 1; // skip initial '(' char - for (; i < fullMethodName.Length; i++) - { - switch (fullMethodName[i]) - { - case ')': - if (types.Any()) - { - parameterTypes = types.ToArray(); - } - return i + 1; // consume right parens - case ',': - break; - default: - i = ParseParameterType(fullMethodName, i, out var parameterType); - types.Add(parameterType); - break; - } - } - - string message = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorIncompleteManagedName); - throw new InvalidManagedNameException(message); - } - - private static int ParseParameterType(string fullMethodName, int start, out string parameterType) - { - parameterType = string.Empty; - - int i = start; - for (; i < fullMethodName.Length; i++) - { - switch (fullMethodName[i]) - { - case '<': - i = ParseGenericBrackets(fullMethodName, i + 1); - break; - case '[': - i = ParseArrayBrackets(fullMethodName, i + 1); - break; - case ',': - case ')': - parameterType = Capture(fullMethodName, start, i); - return i - 1; - case var w when char.IsWhiteSpace(w): - string message = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorWhitespaceNotValid, i); - throw new InvalidManagedNameException(message); - } - } - return i; - } - - private static int ParseArrayBrackets(string fullMethodName, int start) - { - for (int i = start; i < fullMethodName.Length; i++) - { - switch (fullMethodName[i]) - { - case ']': - return i; - case var w when char.IsWhiteSpace(w): - string msg = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorWhitespaceNotValid, i); - throw new InvalidManagedNameException(msg); - } - } - - string message = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorIncompleteManagedName); - throw new InvalidManagedNameException(message); - } - - private static int ParseGenericBrackets(string fullMethodName, int start) - { - for (int i = start; i < fullMethodName.Length; i++) - { - switch (fullMethodName[i]) - { - case '<': - i = ParseGenericBrackets(fullMethodName, i + 1); - break; - case '>': - return i; - case var w when char.IsWhiteSpace(w): - string msg = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorWhitespaceNotValid, i); - throw new InvalidManagedNameException(msg); - } - } - - string message = string.Format(CultureInfo.CurrentCulture, ManagedNameMessages.ErrorIncompleteManagedName); - throw new InvalidManagedNameException(message); - } - } -} diff --git a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj index e0bcb43aa0..ac7507c007 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj +++ b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj @@ -78,7 +78,6 @@ - TextTemplatingFileGenerator @@ -91,11 +90,6 @@ True CommonResources.resx - - True - True - ManagedNameMessages.resx - True True @@ -108,18 +102,11 @@ Resources\CommonResources.tt CommonResources.Designer.cs - - ResXFileCodeGenerator - ManagedNameMessages.Designer.cs - ResXFileCodeGenerator Resources.Designer.cs - - - Microsoft.VisualStudio.TestPlatform.ObjectModel diff --git a/src/Microsoft.TestPlatform.ObjectModel/TestCase.cs b/src/Microsoft.TestPlatform.ObjectModel/TestCase.cs index 7728529e6b..5dd1f45ded 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/TestCase.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/TestCase.cs @@ -10,7 +10,6 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel using System.Linq; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; - using System.Reflection; /// /// Stores information about a test case. @@ -29,8 +28,6 @@ public sealed class TestCase : TestObject private string displayName; private string fullyQualifiedName; private string source; - private string managedMethod; - private string managedType; #region Constructor @@ -66,64 +63,6 @@ public TestCase(string fullyQualifiedName, Uri executorUri, string source) this.Source = source; this.LineNumber = -1; } - - /// - /// Initializes a new instance of the class. - /// - /// - /// Fully qualified name of the test case. - /// - /// - /// Managed method to extract the values of and . - /// - /// - /// The Uri of the executor to use for running this test. - /// - /// - /// Test container source from which the test is discovered. - /// - /// - /// If is specified, TestId will be calculated based on that instead of . - /// - public TestCase(string fullyQualifiedName, MethodBase method, Uri executorUri, string source) - : this(fullyQualifiedName, executorUri, source) - { - ValidateArg.NotNull(method, nameof(method)); - - ManagedNameUtilities.ManagedNameHelper.GetManagedName(method, out var managedType, out var managedMethod); - - ManagedType = managedType; - ManagedMethod = managedMethod; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// Fully qualified name of the test case. - /// - /// - /// Managed method to extract the values of and . - /// - /// - /// The Uri of the executor to use for running this test. - /// - /// - /// Test container source from which the test is discovered. - /// - /// - /// If and are specified, TestId will be calculated based on those instead of . - /// - public TestCase(string fullyQualifiedName, string managedType, string managedMethod, Uri executorUri, string source) - : this(fullyQualifiedName, executorUri, source) - { - ValidateArg.NotNullOrWhiteSpace(managedType, nameof(managedType)); - ValidateArg.NotNullOrWhiteSpace(managedMethod, nameof(managedMethod)); - - ManagedType = managedType; - ManagedMethod = managedMethod; - } - #endregion #region Properties @@ -132,7 +71,7 @@ public TestCase(string fullyQualifiedName, string managedType, string managedMet /// LocalExtensionData which can be used by Adapter developers for local transfer of extended properties. /// Note that this data is available only for in-Proc execution, and may not be available for OutProc executors /// - public Object LocalExtensionData + public object LocalExtensionData { get { return localExtensionData; } set { localExtensionData = value; } @@ -165,34 +104,6 @@ public Guid Id } } - /// - /// Gets or sets the fully specified type name metadata format. - /// - /// - /// NamespaceA.NamespaceB.ClassName`1+InnerClass`2 - /// - [DataMember] - public string ManagedType { - get => managedType; - - // defaultId should be reset as it is based on ManagedType, ManagedMethod and Source. - set => SetVariableAndResetId(ref managedType, value); - } - - /// - /// Gets or sets the fully specified method name metadata format. - /// - /// - /// MethodName`2(ParamTypeA,ParamTypeB,�) - /// - [DataMember] - public string ManagedMethod { - get => managedMethod; - - // defaultId should be reset as it is based on ManagedType, ManagedMethod and Source. - set => SetVariableAndResetId(ref managedMethod, value); - } - /// /// Gets or sets the fully qualified name of the test case. /// @@ -213,14 +124,9 @@ public string DisplayName { get { - if(string.IsNullOrEmpty(this.displayName)) + if (string.IsNullOrEmpty(this.displayName)) { - if (this.HasManagedMethodAndType) - { - return $"{managedType}.{ManagedMethod}"; - } - - return this.FullyQualifiedName; + return this.GetFullyQualifiedName(); } return this.displayName; @@ -288,24 +194,6 @@ public override IEnumerable Properties } } - /// - /// Returns true if both and are not null or whitespace. - /// - public bool HasManagedMethodAndType => !string.IsNullOrWhiteSpace(ManagedType) && !string.IsNullOrWhiteSpace(ManagedMethod); - - /// - public override string ToString() - { - if (this.HasManagedMethodAndType) - { - return $"{ManagedType}.{ManagedMethod}"; - } - else - { - return this.FullyQualifiedName; - } - } - #endregion #region private methods @@ -340,18 +228,11 @@ private Guid GetTestId() // We still need to handle parameters in the case of a Theory or TestGroup of test cases that are only // distinguished by parameters. - var testcaseFullName = this.ExecutorUri + source; - + var testcaseFullName = this.ExecutorUri + source; + // If ManagedType and ManagedMethod properties are filled than TestId should be based on those. - if (this.HasManagedMethodAndType) - { - testcaseFullName += $"{managedType}.{managedMethod}"; - } - else - { - testcaseFullName += this.FullyQualifiedName; - } - + testcaseFullName += this.GetFullyQualifiedName(); + return EqtHash.GuidFromString(testcaseFullName); } @@ -361,6 +242,12 @@ private void SetVariableAndResetId(ref T variable, T value) this.defaultId = Guid.Empty; } + private void SetPropertyAndResetId(TestProperty property, T value) + { + SetPropertyValue(property, value); + this.defaultId = Guid.Empty; + } + #endregion #region Protected Methods @@ -383,10 +270,6 @@ protected override object ProtectedGetPropertyValue(TestProperty property, objec return this.ExecutorUri; case "TestCase.FullyQualifiedName": return this.FullyQualifiedName; - case "TestCase.ManagedType": - return this.ManagedType; - case "TestCase.ManagedMethod": - return this.ManagedMethod; case "TestCase.Id": return this.Id; case "TestCase.LineNumber": @@ -424,14 +307,6 @@ protected override void ProtectedSetPropertyValue(TestProperty property, object this.FullyQualifiedName = value as string; return; - case "TestCase.ManagedType": - this.ManagedType = value as string; - return; - - case "TestCase.ManagedMethod": - this.ManagedMethod = value as string; - return; - case "TestCase.Id": this.Id = value is Guid ? (Guid)value : Guid.Parse(value as string); return; @@ -450,6 +325,32 @@ protected override void ProtectedSetPropertyValue(TestProperty property, object } #endregion + + #region ManagedName and ManagedType implementations + + private static readonly TestProperty ManagedTypeProperty = TestProperty.Register("TestCase.ManagedType", "ManagedType", string.Empty, string.Empty, typeof(string), o => !string.IsNullOrWhiteSpace(o as string), TestPropertyAttributes.Hidden, typeof(TestCase)); + private static readonly TestProperty ManagedMethodProperty = TestProperty.Register("TestCase.ManagedMethod", "ManagedMethod", string.Empty, string.Empty, typeof(string), o => !string.IsNullOrWhiteSpace(o as string), TestPropertyAttributes.Hidden, typeof(TestCase)); + + private bool ContainsManagedMethodAndType => !string.IsNullOrWhiteSpace(ManagedMethod) && !string.IsNullOrWhiteSpace(ManagedType); + + private string ManagedType + { + get => GetPropertyValue(ManagedTypeProperty, null); + set => SetPropertyAndResetId(ManagedTypeProperty, value); + } + + private string ManagedMethod + { + get => GetPropertyValue(ManagedMethodProperty, null); + set => SetPropertyAndResetId(ManagedMethodProperty, value); + } + + private string GetFullyQualifiedName() => ContainsManagedMethodAndType ? $"{ManagedType}.{ManagedMethod}" : FullyQualifiedName; + + #endregion + + /// + public override string ToString() => this.GetFullyQualifiedName(); } /// @@ -465,8 +366,6 @@ public static class TestCaseProperties /// private const string IdLabel = "Id"; private const string FullyQualifiedNameLabel = "FullyQualifiedName"; - private const string ManagedTypeLabel = "ManagedType"; - private const string ManagedMethodLabel = "ManagedMethod"; private const string NameLabel = "Name"; private const string ExecutorUriLabel = "Executor Uri"; private const string SourceLabel = "Source"; @@ -475,31 +374,12 @@ public static class TestCaseProperties #endregion - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly TestProperty Id = TestProperty.Register("TestCase.Id", IdLabel, string.Empty, string.Empty, typeof(Guid), ValidateGuid, TestPropertyAttributes.Hidden, typeof(TestCase)); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly TestProperty FullyQualifiedName = TestProperty.Register("TestCase.FullyQualifiedName", FullyQualifiedNameLabel, string.Empty, string.Empty, typeof(string), ValidateName, TestPropertyAttributes.Hidden, typeof(TestCase)); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - public static readonly TestProperty ManagedType = TestProperty.Register("TestCase.ManagedType", ManagedTypeLabel, string.Empty, string.Empty, typeof(string), ValidateName, TestPropertyAttributes.Hidden, typeof(TestCase)); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - public static readonly TestProperty ManagedMethod = TestProperty.Register("TestCase.ManagedMethod", ManagedMethodLabel, string.Empty, string.Empty, typeof(string), ValidateName, TestPropertyAttributes.Hidden, typeof(TestCase)); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly TestProperty DisplayName = TestProperty.Register("TestCase.DisplayName", NameLabel, string.Empty, string.Empty, typeof(string), ValidateDisplay, TestPropertyAttributes.None, typeof(TestCase)); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly TestProperty ExecutorUri = TestProperty.Register("TestCase.ExecutorUri", ExecutorUriLabel, string.Empty, string.Empty, typeof(Uri), ValidateExecutorUri, TestPropertyAttributes.Hidden, typeof(TestCase)); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly TestProperty Source = TestProperty.Register("TestCase.Source", SourceLabel, typeof(string), typeof(TestCase)); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly TestProperty CodeFilePath = TestProperty.Register("TestCase.CodeFilePath", FilePathLabel, typeof(string), typeof(TestCase)); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly TestProperty LineNumber = TestProperty.Register("TestCase.LineNumber", LineNumberLabel, typeof(int), TestPropertyAttributes.Hidden, typeof(TestCase)); internal static TestProperty[] Properties { get; } = @@ -508,8 +388,6 @@ public static class TestCaseProperties DisplayName, ExecutorUri, FullyQualifiedName, - ManagedType, - ManagedMethod, Id, LineNumber, Source @@ -531,7 +409,6 @@ private static bool ValidateExecutorUri(object value) return value != null; } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "Required to validate the input value.")] private static bool ValidateGuid(object value) { try diff --git a/src/package/nuspec/Microsoft.TestPlatform.AdapterUtilities.nuspec b/src/package/nuspec/Microsoft.TestPlatform.AdapterUtilities.nuspec new file mode 100644 index 0000000000..2dfbe5b36c --- /dev/null +++ b/src/package/nuspec/Microsoft.TestPlatform.AdapterUtilities.nuspec @@ -0,0 +1,51 @@ + + + + Microsoft.TestPlatform.AdapterUtilities + 15.0.0 + Microsoft.TestPlatform.AdapterUtilities + Microsoft + Microsoft + true + + Includes helpers for the Test Platform's modern functionality such as standardized fully qualified names and hierarchical test case names. + + http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + http://go.microsoft.com/fwlink/?LinkID=288859 + Icon.png + https://github.com/microsoft/vstest/ + © Microsoft Corporation. All rights reserved. + vstest visual-studio unittest testplatform mstest microsoft test testing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/FindMethodExtensions.cs b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/FindMethodExtensions.cs similarity index 97% rename from test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/FindMethodExtensions.cs rename to test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/FindMethodExtensions.cs index dee213e414..8455bcb5f2 100644 --- a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/FindMethodExtensions.cs +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/FindMethodExtensions.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.ObjectModel.ManagedNameUtilities.UnitTests +namespace Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities.UnitTests { using Microsoft.CodeAnalysis; diff --git a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/ManagedNameParserTests.cs b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameParserTests.cs similarity index 82% rename from test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/ManagedNameParserTests.cs rename to test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameParserTests.cs index b56b54774c..5747d460da 100644 --- a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/ManagedNameParserTests.cs +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameParserTests.cs @@ -1,9 +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. -namespace Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests +namespace Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities.UnitTests { - using Microsoft.VisualStudio.TestPlatform.ObjectModel.ManagedNameUtilities; + using Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -12,9 +12,9 @@ public class ManagedNameParserTests [TestMethod] public void ParseTypeName() { - (string, string) Parse(string fullTypeName) + (string, string) Parse(string managedTypeName) { - ManagedNameParser.ParseTypeName(fullTypeName, out var namespaceName, out var typeName); + ManagedNameParser.ParseManagedTypeName(managedTypeName, out var namespaceName, out var typeName); return (namespaceName, typeName); }; @@ -29,9 +29,9 @@ public void ParseTypeName() [TestMethod] public void ParseMethodName() { - (string, int, string[]) Parse(string methodName) + (string, int, string[]) Parse(string managedMethodName) { - ManagedNameParser.ParseMethodName(methodName, out var method, out var arity, out var parameterTypes); + ManagedNameParser.ParseManagedMethodName(managedMethodName, out var method, out var arity, out var parameterTypes); return (method, arity, parameterTypes); } @@ -58,7 +58,7 @@ public void ParseInvalidMethodName() { (string, int, string[]) Parse(string methodName) { - ManagedNameParser.ParseMethodName(methodName, out var method, out var arity, out var parameterTypes); + ManagedNameParser.ParseManagedMethodName(methodName, out var method, out var arity, out var parameterTypes); return (method, arity, parameterTypes); } diff --git a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/ManagedNameRoundTripTests.cs b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameRoundTripTests.cs similarity index 80% rename from test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/ManagedNameRoundTripTests.cs rename to test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameRoundTripTests.cs index bc69a9dcc1..5ff18ae6ad 100644 --- a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/ManagedNameRoundTripTests.cs +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameRoundTripTests.cs @@ -1,11 +1,11 @@ // 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.ObjectModel.ManagedNameUtilities.UnitTests +namespace Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities.UnitTests { using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.ManagedNameUtilities; + using Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.IO; @@ -35,8 +35,8 @@ public void Simple1() methodInfo: typeof(TestClasses.Outer).GetMethod("Method0"), containingTypeSymbol: outer, methodSymbol: outer.FindMethod("Method0"), - fullTypeName: "TestClasses.Outer", - fullMethodName: "Method0"); + managedTypeName: "TestClasses.Outer", + managedMethodName: "Method0"); } [TestMethod] @@ -48,8 +48,8 @@ public void Simple2() methodInfo: typeof(TestClasses.Outer).GetMethod("Method1"), containingTypeSymbol: outer, methodSymbol: outer.FindMethod("Method1"), - fullTypeName: "TestClasses.Outer", - fullMethodName: "Method1(System.Int32)"); + managedTypeName: "TestClasses.Outer", + managedMethodName: "Method1(System.Int32)"); } [TestMethod] @@ -61,8 +61,8 @@ public void Simple3() methodInfo: typeof(TestClasses.Outer).GetMethod("Method2"), containingTypeSymbol: outer, methodSymbol: outer.FindMethod("Method2"), - fullTypeName: "TestClasses.Outer", - fullMethodName: "Method2(System.Collections.Generic.List`1)"); + managedTypeName: "TestClasses.Outer", + managedMethodName: "Method2(System.Collections.Generic.List`1)"); } [TestMethod] @@ -74,8 +74,8 @@ public void Simple4() methodInfo: typeof(TestClasses.Outer).GetMethod("Method3"), containingTypeSymbol: outer, methodSymbol: outer.FindMethod("Method3"), - fullTypeName: "TestClasses.Outer", - fullMethodName: "Method3(System.String,System.Int32)"); + managedTypeName: "TestClasses.Outer", + managedMethodName: "Method3(System.String,System.Int32)"); } [TestMethod] @@ -87,8 +87,8 @@ public void Nested1() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method0"), containingTypeSymbol: outerInner, methodSymbol: outerInner.FindMethod("Method0"), - fullTypeName: "TestClasses.Outer+Inner", - fullMethodName: "Method0"); + managedTypeName: "TestClasses.Outer+Inner", + managedMethodName: "Method0"); } [TestMethod] @@ -100,8 +100,8 @@ public void Nested2() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method1"), containingTypeSymbol: outerInner, methodSymbol: outerInner.FindMethod("Method1"), - fullTypeName: "TestClasses.Outer+Inner", - fullMethodName: "Method1(System.Int32)"); + managedTypeName: "TestClasses.Outer+Inner", + managedMethodName: "Method1(System.Int32)"); } [TestMethod] @@ -113,8 +113,8 @@ public void OpenGeneric1() methodInfo: typeof(TestClasses.Outer<>).GetMethod("Method0"), containingTypeSymbol: outerT, methodSymbol: outerT.FindMethod("Method0"), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method0"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method0"); } [TestMethod] @@ -126,8 +126,8 @@ public void OpenGeneric2() methodInfo: typeof(TestClasses.Outer<>).GetMethod("Method1"), containingTypeSymbol: outerT, methodSymbol: outerT.FindMethod("Method1"), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method1(!0)"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method1(!0)"); } [TestMethod] @@ -139,8 +139,8 @@ public void OpenGeneric3() methodInfo: typeof(TestClasses.Outer<>).GetMethod("Method2"), containingTypeSymbol: outerT, methodSymbol: outerT.FindMethod("Method2"), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method2`1(!!0[])"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method2`1(!!0[])"); } [TestMethod] @@ -152,8 +152,8 @@ public void OpenGeneric4() methodInfo: typeof(TestClasses.Outer<>).GetMethod("Method3"), containingTypeSymbol: outerT, methodSymbol: outerT.FindMethod("Method3"), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method3`1(!0,!!0)"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method3`1(!0,!!0)"); } [TestMethod] @@ -165,8 +165,8 @@ public void OpenGenericNested1() methodInfo: typeof(TestClasses.Outer<>.Inner<>).GetMethod("Method0"), containingTypeSymbol: outerTInnterV, methodSymbol: outerTInnterV.FindMethod("Method0"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method0"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method0"); } [TestMethod] @@ -178,8 +178,8 @@ public void OpenGenericNested2() methodInfo: typeof(TestClasses.Outer<>.Inner<>).GetMethod("Method1"), containingTypeSymbol: outerTInnterV, methodSymbol: outerTInnterV.FindMethod("Method1"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method1(!0)"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method1(!0)"); } [TestMethod] @@ -191,8 +191,8 @@ public void OpenGenericNested3() methodInfo: typeof(TestClasses.Outer<>.Inner<>).GetMethod("Method2"), containingTypeSymbol: outerTInnterV, methodSymbol: outerTInnterV.FindMethod("Method2"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method2(!1)"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method2(!1)"); } [TestMethod] @@ -204,8 +204,8 @@ public void OpenGenericNested4() methodInfo: typeof(TestClasses.Outer<>.Inner<>).GetMethod("Method3"), containingTypeSymbol: outerTInnterV, methodSymbol: outerTInnterV.FindMethod("Method3"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method3`1(!0,!!0,!1)"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method3`1(!0,!!0,!1)"); } [TestMethod] @@ -217,8 +217,8 @@ public void OpenGenericNested5() methodInfo: typeof(TestClasses.Outer<>.Inner<>).GetMethod("Method4"), containingTypeSymbol: outerTInnterV, methodSymbol: outerTInnterV.FindMethod("Method4"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method4`2(!!1,!!0)"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method4`2(!!1,!!0)"); } [TestMethod] @@ -230,8 +230,8 @@ public void OpenGenericNested6() methodInfo: typeof(TestClasses.Outer<>.Inner<>.MoreInner<>).GetMethod("Method0"), containingTypeSymbol: outerTInnerVMoreInnerI, methodSymbol: outerTInnerVMoreInnerI.FindMethod("Method0"), - fullTypeName: "TestClasses.Outer`1+Inner`1+MoreInner`1", - fullMethodName: "Method0`1(!0,!1,!2,!!0)"); + managedTypeName: "TestClasses.Outer`1+Inner`1+MoreInner`1", + managedMethodName: "Method0`1(!0,!1,!2,!!0)"); } [TestMethod] @@ -244,8 +244,8 @@ public void ClosedGeneric1() methodInfo: typeof(TestClasses.Outer).GetMethod("Method0"), containingTypeSymbol: outerTInt, methodSymbol: outerTInt.FindMethod("Method0"), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method0"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method0"); } [TestMethod] @@ -258,8 +258,8 @@ public void ClosedGeneric2() methodInfo: typeof(TestClasses.Outer).GetMethod("Method1"), containingTypeSymbol: outerTInt, methodSymbol: outerTInt.FindMethod("Method1"), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method1(!0)"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method1(!0)"); } [TestMethod] @@ -272,8 +272,8 @@ public void ClosedGeneric3() methodInfo: typeof(TestClasses.Outer).GetMethod("Method2"), containingTypeSymbol: outerTInt, methodSymbol: outerTInt.FindMethod("Method2"), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method2`1(!!0[])"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method2`1(!!0[])"); } [TestMethod] @@ -286,8 +286,8 @@ public void ClosedGeneric4() methodInfo: typeof(TestClasses.Outer).GetMethod("Method3"), containingTypeSymbol: outerTInt, methodSymbol: outerTInt.FindMethod("Method3"), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method3`1(!0,!!0)"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method3`1(!0,!!0)"); } [TestMethod] @@ -302,8 +302,8 @@ public void ClosedGenericNested1() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method0"), containingTypeSymbol: outerTIntInnerVString, methodSymbol: outerTIntInnerVString.FindMethod("Method0"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method0"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method0"); } [TestMethod] @@ -318,8 +318,8 @@ public void ClosedGenericNested2() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method1"), containingTypeSymbol: outerTIntInnerVString, methodSymbol: outerTIntInnerVString.FindMethod("Method1"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method1(!0)"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method1(!0)"); } [TestMethod] @@ -334,8 +334,8 @@ public void ClosedGenericNested3() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method2"), containingTypeSymbol: outerTIntInnerVString, methodSymbol: outerTIntInnerVString.FindMethod("Method2"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method2(!1)"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method2(!1)"); } [TestMethod] @@ -350,8 +350,8 @@ public void ClosedGenericNested4() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method3"), containingTypeSymbol: outerTIntInnerVString, methodSymbol: outerTIntInnerVString.FindMethod("Method3"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method3`1(!0,!!0,!1)"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method3`1(!0,!!0,!1)"); } [TestMethod] @@ -366,8 +366,8 @@ public void ClosedGenericNested5() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method4"), containingTypeSymbol: outerTIntInnerVString, methodSymbol: outerTIntInnerVString.FindMethod("Method4"), - fullTypeName: "TestClasses.Outer`1+Inner`1", - fullMethodName: "Method4`2(!!1,!!0)"); + managedTypeName: "TestClasses.Outer`1+Inner`1", + managedMethodName: "Method4`2(!!1,!!0)"); } [TestMethod] @@ -381,8 +381,8 @@ public void ClosedGenericMethod1() methodInfo: typeof(TestClasses.Outer).GetMethod("Method3").MakeGenericMethod(typeof(string)), containingTypeSymbol: outerTInt, methodSymbol: outerTInt.FindMethod("Method3").Construct(@string), - fullTypeName: "TestClasses.Outer`1", - fullMethodName: "Method3`1(!0,!!0)"); + managedTypeName: "TestClasses.Outer`1", + managedMethodName: "Method3`1(!0,!!0)"); } [TestMethod] @@ -395,8 +395,8 @@ public void ClosedGenericMethod2() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method2").MakeGenericMethod(typeof(int)), containingTypeSymbol: outerInner, methodSymbol: outerInner.FindMethod("Method2").Construct(@int), - fullTypeName: "TestClasses.Outer+Inner", - fullMethodName: "Method2`1(System.Int32)"); + managedTypeName: "TestClasses.Outer+Inner", + managedMethodName: "Method2`1(System.Int32)"); } [TestMethod] @@ -411,8 +411,8 @@ public void ClosedGenericMethod3() methodInfo: typeof(TestClasses.Outer.Inner).GetMethod("Method3").MakeGenericMethod(typeof(float), typeof(string)), containingTypeSymbol: outerInner, methodSymbol: outerInner.FindMethod("Method3").Construct(@float, @string), - fullTypeName: "TestClasses.Outer+Inner", - fullMethodName: "Method3`2(System.Int32)"); + managedTypeName: "TestClasses.Outer+Inner", + managedMethodName: "Method3`2(System.Int32)"); } [TestMethod] @@ -424,8 +424,8 @@ public void ExplicitInterfaceImplementation1() methodInfo: typeof(TestClasses.Impl).GetMethod("TestClasses.IImplementation.ImplMethod0", PrivateBindingFlags), containingTypeSymbol: impl, methodSymbol: impl.FindMethod("TestClasses.IImplementation.ImplMethod0"), - fullTypeName: "TestClasses.Impl", - fullMethodName: "TestClasses.IImplementation.ImplMethod0"); + managedTypeName: "TestClasses.Impl", + managedMethodName: "TestClasses.IImplementation.ImplMethod0"); } [TestMethod] @@ -437,8 +437,8 @@ public void ExplicitInterfaceImplementation2() methodInfo: typeof(TestClasses.Impl).GetMethod("TestClasses.IImplementation.ImplMethod1", PrivateBindingFlags), containingTypeSymbol: impl, methodSymbol: impl.FindMethod("TestClasses.IImplementation.ImplMethod1"), - fullTypeName: "TestClasses.Impl", - fullMethodName: "TestClasses.IImplementation.ImplMethod1(System.Int32)"); + managedTypeName: "TestClasses.Impl", + managedMethodName: "TestClasses.IImplementation.ImplMethod1(System.Int32)"); } [TestMethod] @@ -450,8 +450,8 @@ public void GenericExplicitInterfaceImplementation1() methodInfo: typeof(TestClasses.Impl<>).GetMethod("TestClasses.IImplementation.ImplMethod0", PrivateBindingFlags), containingTypeSymbol: implT, methodSymbol: implT.FindMethod("TestClasses.IImplementation.ImplMethod0"), - fullTypeName: "TestClasses.Impl`1", - fullMethodName: "TestClasses.IImplementation.ImplMethod0"); + managedTypeName: "TestClasses.Impl`1", + managedMethodName: "TestClasses.IImplementation.ImplMethod0"); } [TestMethod] @@ -463,8 +463,8 @@ public void GenericExplicitInterfaceImplementation2() methodInfo: typeof(TestClasses.Impl<>).GetMethod("TestClasses.IImplementation.ImplMethod1", PrivateBindingFlags), containingTypeSymbol: implT, methodSymbol: implT.FindMethod("TestClasses.IImplementation.ImplMethod1"), - fullTypeName: "TestClasses.Impl`1", - fullMethodName: "TestClasses.IImplementation.ImplMethod1(!0)"); + managedTypeName: "TestClasses.Impl`1", + managedMethodName: "TestClasses.IImplementation.ImplMethod1(!0)"); } [TestMethod] @@ -476,8 +476,8 @@ public void GenericExplicitInterfaceImplementation3() methodInfo: typeof(TestClasses.Impl<>).GetMethod("TestClasses.IImplementation.ImplMethod2", PrivateBindingFlags), containingTypeSymbol: implT, methodSymbol: implT.FindMethod("TestClasses.IImplementation.ImplMethod2"), - fullTypeName: "TestClasses.Impl`1", - fullMethodName: "TestClasses.IImplementation.ImplMethod2`1(!0,!!0,System.String)"); + managedTypeName: "TestClasses.Impl`1", + managedMethodName: "TestClasses.IImplementation.ImplMethod2`1(!0,!!0,System.String)"); } [TestMethod] @@ -489,8 +489,8 @@ public void Inheritance1() methodInfo: typeof(TestClasses.OuterPrime).GetMethod("Method3"), containingTypeSymbol: outerPrime, methodSymbol: outerPrime.FindMethod("Method3"), - fullTypeName: "TestClasses.OuterPrime", - fullMethodName: "Method3(System.String,System.Int32)"); + managedTypeName: "TestClasses.OuterPrime", + managedMethodName: "Method3(System.String,System.Int32)"); } [TestMethod] @@ -502,8 +502,8 @@ public void Inheritance2() methodInfo: typeof(TestClasses.OuterPrime<>).GetMethod("Method3"), containingTypeSymbol: outerPrimeZ, methodSymbol: outerPrimeZ.FindMethod("Method3"), - fullTypeName: "TestClasses.OuterPrime`1", - fullMethodName: "Method3`1(!0,!!0)"); + managedTypeName: "TestClasses.OuterPrime`1", + managedMethodName: "Method3`1(!0,!!0)"); } [TestMethod] @@ -515,8 +515,8 @@ public void Inheritance3() methodInfo: typeof(TestClasses.OuterPrime<,>).GetMethod("Method3"), containingTypeSymbol: outerPrimeYZ, methodSymbol: outerPrimeYZ.FindMethod("Method3"), - fullTypeName: "TestClasses.OuterPrime`2", - fullMethodName: "Method3`1(!1,!!0)"); + managedTypeName: "TestClasses.OuterPrime`2", + managedMethodName: "Method3`1(!1,!!0)"); } [TestMethod] @@ -528,8 +528,8 @@ public void Inheritance4() methodInfo: typeof(TestClasses.OuterString).GetMethod("Method3"), containingTypeSymbol: outerString, methodSymbol: outerString.FindMethod("Method3"), - fullTypeName: "TestClasses.OuterString", - fullMethodName: "Method3`1(System.String,!!0)"); + managedTypeName: "TestClasses.OuterString", + managedMethodName: "Method3`1(System.String,!!0)"); } [TestMethod] @@ -541,8 +541,8 @@ public void Overloads1() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0()"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 0), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0"); } [TestMethod] @@ -555,8 +555,8 @@ public void Overloads2() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0(Int32)"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 0, @int), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0(System.Int32)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0(System.Int32)"); } [TestMethod] @@ -569,8 +569,8 @@ public void Overloads3() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0(Int32, TestClasses.Overloads)"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 0, @int, overloads), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0(System.Int32,TestClasses.Overloads)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0(System.Int32,TestClasses.Overloads)"); } [TestMethod] @@ -584,8 +584,8 @@ public void Overloads4() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0(Int32*)"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 0, intptr), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0(System.Int32*)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0(System.Int32*)"); } [TestMethod] @@ -598,8 +598,8 @@ public void Overloads5() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0(System.Object)"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 0, dynamic), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0(System.Object)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0(System.Object)"); } [TestMethod] @@ -611,8 +611,8 @@ public void Overloads6() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0[U](U)"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 1, 1, m => m.Parameters.Single().Type == m.TypeParameters.Single()), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1(!!0)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1(!!0)"); } [TestMethod] @@ -624,8 +624,8 @@ public void Overloads7() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0[U]()"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 1), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1"); } [TestMethod] @@ -637,8 +637,8 @@ public void Overloads8() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0[U,T]()"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 2), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`2"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`2"); } [TestMethod] @@ -653,8 +653,8 @@ public void Overloads9() m => m.Parameters.Single().Type is IArrayTypeSymbol arrayType && arrayType.Rank == 1 && arrayType.ElementType == m.TypeParameters.Single()), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1(!!0[])"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1(!!0[])"); } [TestMethod] @@ -671,8 +671,8 @@ public void Overloads10() arrayType.ElementType is IArrayTypeSymbol innerArrayType && innerArrayType.Rank == 1 && innerArrayType.ElementType == m.TypeParameters.Single()), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1(!!0[][])"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1(!!0[][])"); } [TestMethod] @@ -687,8 +687,8 @@ public void Overloads11() m => m.Parameters.Single().Type is IArrayTypeSymbol arrayType && arrayType.Rank == 2 && arrayType.ElementType == m.TypeParameters.Single()), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1(!!0[,])"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1(!!0[,])"); } [TestMethod] @@ -703,8 +703,8 @@ public void Overloads12() m => m.Parameters.Single().Type is IArrayTypeSymbol arrayType && arrayType.Rank == 3 && arrayType.ElementType == m.TypeParameters.Single()), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1(!!0[,,])"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1(!!0[,,])"); } [TestMethod] @@ -718,8 +718,8 @@ public void Overloads13() methodInfo: typeof(TestClasses.Overloads).FindMethod("Void Overload0[U](System.Collections.Generic.List`1[System.Int32])"), containingTypeSymbol: overloads, methodSymbol: overloads.FindMethod("Overload0", 1, listInt), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1(System.Collections.Generic.List`1)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1(System.Collections.Generic.List`1)"); } [TestMethod] @@ -736,8 +736,8 @@ public void Overloads14() m.Parameters.Single().Type is INamedTypeSymbol p && p.OriginalDefinition == list && p.TypeArguments.Single() == m.TypeParameters.Single()), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1(System.Collections.Generic.List`1)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1(System.Collections.Generic.List`1)"); } [TestMethod] @@ -757,8 +757,8 @@ public void Overloads15() m.Parameters.Last() is INamedTypeSymbol p2 && p2.OriginalDefinition == tuple2 && p2.TypeArguments.SequenceEqual(m.TypeParameters.Reverse())), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`2(System.Tuple`2,System.Tuple`2)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`2(System.Tuple`2,System.Tuple`2)"); } [TestMethod] @@ -777,8 +777,8 @@ public void Overloads16() p.OriginalDefinition == tuple1 && p.TypeArguments.Single() is INamedTypeSymbol t && t.OriginalDefinition == tuple2), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0(System.Tuple`1>)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0(System.Tuple`1>)"); } [TestMethod] @@ -796,8 +796,8 @@ public void Overloads17() m.Parameters.Single().Type is INamedTypeSymbol p && p.OriginalDefinition == tuple2 && p.TypeArguments.All(t => t.OriginalDefinition == tuple1)), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0(System.Tuple`2,System.Tuple`1>)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0(System.Tuple`2,System.Tuple`1>)"); } [TestMethod] @@ -815,8 +815,8 @@ public void Overloads18() p.OriginalDefinition == tuple1 && p.TypeArguments.Single() is INamedTypeSymbol t && t.OriginalDefinition == tuple1), - fullTypeName: "TestClasses.Overloads", - fullMethodName: "Overload0`1(System.Tuple`1>>)"); + managedTypeName: "TestClasses.Overloads", + managedMethodName: "Overload0`1(System.Tuple`1>>)"); } #region Helpers @@ -824,45 +824,45 @@ private void VerifyRoundTrip( MethodInfo methodInfo, INamedTypeSymbol containingTypeSymbol, IMethodSymbol methodSymbol, - string fullTypeName, - string fullMethodName) + string managedTypeName, + string managedMethodName) { - VerifyRoundTripFromMethodInfo(methodInfo, fullTypeName, fullMethodName); - VerifyRoundTripFromName(fullTypeName, fullMethodName, methodInfo); - // VerifyRoundTripFromMethodSymbol(containingTypeSymbol, methodSymbol, fullTypeName, fullMethodName); - // VerifyRoundTripFromName(fullTypeName, fullMethodName, containingTypeSymbol, methodSymbol); + VerifyRoundTripFromMethodInfo(methodInfo, managedTypeName, managedMethodName); + VerifyRoundTripFromName(managedTypeName, managedMethodName, methodInfo); + // VerifyRoundTripFromMethodSymbol(containingTypeSymbol, methodSymbol, managedTypeName, managedMethodName); + // VerifyRoundTripFromName(managedTypeName, managedMethodName, containingTypeSymbol, methodSymbol); } private void VerifyRoundTripFromMethodInfo( MethodInfo methodInfo, - string expectedFullTypeName, - string expectedFullMethodName) + string expectedManagedTypeName, + string expectedManagedMethodName) { // Generate the fqn for the Reflection MethodInfo - ManagedNameHelper.GetManagedName(methodInfo, out var fullTypeName, out var fullMethodName); + ManagedNameHelper.GetManagedName(methodInfo, out var managedTypeName, out var managedMethodName); - Assert.AreEqual(expectedFullTypeName, fullTypeName); - Assert.AreEqual(expectedFullMethodName, fullMethodName); + Assert.AreEqual(expectedManagedTypeName, managedTypeName); + Assert.AreEqual(expectedManagedMethodName, managedMethodName); // Lookup the Reflection MethodInfo using fullTypeName and fullMethodName - var roundTrippedMethodInfo = ManagedNameHelper.GetManagedName( + var roundTrippedMethodInfo = ManagedNameHelper.GetMethod( Assembly.GetExecutingAssembly(), - fullTypeName, - fullMethodName); + managedTypeName, + managedMethodName); Assert.AreEqual(methodInfo.MetadataToken, roundTrippedMethodInfo.MetadataToken); } private void VerifyRoundTripFromName( - string fullTypeName, - string fullMethodName, + string managedTypeName, + string managedMethodName, MethodInfo expectedMethodInfo) { // Lookup the Reflection MethodInfo using fullTypeName and fullMethodName - var methodInfo = ManagedNameHelper.GetManagedName( + var methodInfo = ManagedNameHelper.GetMethod( Assembly.GetExecutingAssembly(), - fullTypeName, - fullMethodName); + managedTypeName, + managedMethodName); Assert.AreEqual(expectedMethodInfo.MetadataToken, methodInfo.MetadataToken); @@ -872,8 +872,8 @@ private void VerifyRoundTripFromName( out var roundTrippedFullTypeName, out var roundTrippedFullMethodName); - Assert.AreEqual(fullTypeName, roundTrippedFullTypeName); - Assert.AreEqual(fullMethodName, roundTrippedFullMethodName); + Assert.AreEqual(managedTypeName, roundTrippedFullTypeName); + Assert.AreEqual(managedMethodName, roundTrippedFullMethodName); } // private void VerifyRoundTripFromMethodSymbol( diff --git a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests.csproj b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj similarity index 81% rename from test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests.csproj rename to test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj index 87797a50dc..dabed0d2f0 100644 --- a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests.csproj +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj @@ -8,7 +8,7 @@ netcoreapp2.1 Exe - Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests + Microsoft.TestPlatform.AdapterUtilities.UnitTests true 3.8.0-3.20427.2 $(NoWarn);RS1024 @@ -19,12 +19,16 @@ - + + + + + PreserveNewest - - + + diff --git a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/Program.cs b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Program.cs similarity index 78% rename from test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/Program.cs rename to test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Program.cs index fbe5689406..e6fb5d296f 100644 --- a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/Program.cs +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Program.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.ObjectModel.ManagedNameUtilities.UnitTests +namespace Microsoft.TestPlatform.AdapterUtilities.UnitTests { public static class Program { diff --git a/test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/TestClasses.cs b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/TestClasses.cs similarity index 100% rename from test/Microsoft.TestPlatform.ObjectModel.ManagedNameUtilities.UnitTests/TestClasses.cs rename to test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/TestClasses.cs diff --git a/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Serialization/TestResultSerializationTests.cs b/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Serialization/TestResultSerializationTests.cs index 7f16a8a11b..f84c978312 100644 --- a/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Serialization/TestResultSerializationTests.cs +++ b/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Serialization/TestResultSerializationTests.cs @@ -238,7 +238,7 @@ public void TestResultObjectShouldSerializeAttachmentsV2(int version) result.StartTime = default(DateTimeOffset); result.EndTime = default(DateTimeOffset); result.Attachments.Add(new AttachmentSet(new Uri("http://dummyUri"), "sampleAttachment")); - var expectedJson = "{\"TestCase\":{\"Id\":\"28e7a7ed-8fb9-05b7-5e90-4a8c52f32b5b\",\"ManagedType\":null,\"ManagedMethod\":null,\"FullyQualifiedName\":\"sampleTestClass.sampleTestCase\",\"DisplayName\":\"sampleTestClass.sampleTestCase\",\"ExecutorUri\":\"executor://sampleTestExecutor\",\"Source\":\"sampleTest.dll\",\"CodeFilePath\":null,\"LineNumber\":-1,\"Properties\":[]},\"Attachments\":[{\"Uri\":\"http://dummyUri\",\"DisplayName\":\"sampleAttachment\",\"Attachments\":[]}],\"Outcome\":0,\"ErrorMessage\":null,\"ErrorStackTrace\":null,\"DisplayName\":null,\"Messages\":[],\"ComputerName\":null,\"Duration\":\"00:00:00\",\"StartTime\":\"0001-01-01T00:00:00+00:00\",\"EndTime\":\"0001-01-01T00:00:00+00:00\",\"Properties\":[]}"; + var expectedJson = "{\"TestCase\":{\"Id\":\"28e7a7ed-8fb9-05b7-5e90-4a8c52f32b5b\",\"FullyQualifiedName\":\"sampleTestClass.sampleTestCase\",\"DisplayName\":\"sampleTestClass.sampleTestCase\",\"ExecutorUri\":\"executor://sampleTestExecutor\",\"Source\":\"sampleTest.dll\",\"CodeFilePath\":null,\"LineNumber\":-1,\"Properties\":[]},\"Attachments\":[{\"Uri\":\"http://dummyUri\",\"DisplayName\":\"sampleAttachment\",\"Attachments\":[]}],\"Outcome\":0,\"ErrorMessage\":null,\"ErrorStackTrace\":null,\"DisplayName\":null,\"Messages\":[],\"ComputerName\":null,\"Duration\":\"00:00:00\",\"StartTime\":\"0001-01-01T00:00:00+00:00\",\"EndTime\":\"0001-01-01T00:00:00+00:00\",\"Properties\":[]}"; var json = Serialize(result, version); From 358ec6169542cf4c004d95cad1d3a45a8b8c4a6d Mon Sep 17 00:00:00 2001 From: Medeni Baykal <433724+Haplois@users.noreply.github.com> Date: Wed, 27 Jan 2021 18:33:07 +0100 Subject: [PATCH 45/46] Including `Microsoft.TestPlatform.AdapterUtilities` in signing (#2719) * Included missing assemblies in signing. --- src/package/sign/sign.proj | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/package/sign/sign.proj b/src/package/sign/sign.proj index 4ea8ef5a88..ceb7fdc058 100644 --- a/src/package/sign/sign.proj +++ b/src/package/sign/sign.proj @@ -32,6 +32,9 @@ $(ArtifactsBaseDirectory)netstandard2.0\ + + + $(ArtifactsBaseDirectory)uap10.0\ $(ArtifactsBaseDirectory)obj\$(BuildConfiguration)\$(TargetFramework)\$(TargetRuntime)\ @@ -332,6 +335,7 @@ + @@ -340,6 +344,9 @@ + + + @@ -353,6 +360,7 @@ + @@ -462,6 +470,11 @@ Microsoft400 StrongName + + + Microsoft400 + StrongName + Microsoft400 @@ -527,6 +540,12 @@ IntermediatesDirectory="$(IntermediatesDirectory)" Type="$(SignType)" /> + + + Date: Fri, 29 Jan 2021 10:46:29 +0100 Subject: [PATCH 46/46] Updating nuget Pdb2Pdb package (#2720) * Adding new Pdb2Pdb package and change to licence tag because of warning * Fixing license * Formating fixes --- eng/Version.Details.xml | 2 +- scripts/PortableToFullPdb.ps1 | 6 +- scripts/build.ps1 | 4 ++ scripts/build.sh | 1 + scripts/verify-nupkgs.ps1 | 22 +++---- src/package/external/external.csproj | 4 +- src/package/licenses/LICENSE_NET.txt | 65 +++++++++++++++++++ src/package/licenses/LICENSE_VS.txt | 59 +++++++++++++++++ .../nuspec/Microsoft.CodeCoverage.nuspec | 4 +- .../nuspec/Microsoft.NET.Test.Sdk.nuspec | 4 +- ...osoft.TestPlatform.AdapterUtilities.nuspec | 4 +- .../Microsoft.TestPlatform.Portable.nuspec | 4 +- .../nuspec/Microsoft.TestPlatform.nuspec | 4 +- src/package/nuspec/TestPlatform.Build.nuspec | 4 +- src/package/nuspec/TestPlatform.CLI.nuspec | 4 +- .../TestPlatform.Extensions.TrxLogger.nuspec | 4 +- .../nuspec/TestPlatform.ObjectModel.nuspec | 6 +- .../nuspec/TestPlatform.TestHost.nuspec | 4 +- .../TestPlatform.TranslationLayer.nuspec | 4 +- ...rosoft.TestPlatform.Asset.NativeCPP.nuspec | 3 +- ...icrosoft.TestPlatform.QTools.Assets.nuspec | 3 +- 21 files changed, 173 insertions(+), 42 deletions(-) create mode 100644 src/package/licenses/LICENSE_NET.txt create mode 100644 src/package/licenses/LICENSE_VS.txt diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 23fa092e85..bcc7c5c8a9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -36,7 +36,7 @@ - + https://github.com/dotnet/symreader-converter c5ba7c88f92e2dde156c324a8c8edc04d9fa4fe0 diff --git a/scripts/PortableToFullPdb.ps1 b/scripts/PortableToFullPdb.ps1 index 3d410a655d..f81a89cd83 100644 --- a/scripts/PortableToFullPdb.ps1 +++ b/scripts/PortableToFullPdb.ps1 @@ -16,13 +16,13 @@ $TP_ROOT_DIR = (Get-Item (Split-Path $MyInvocation.MyCommand.Path)).Parent.FullN $TP_PACKAGES_DIR = Join-Path $TP_ROOT_DIR "packages" $TP_OUT_DIR = Join-Path $TP_ROOT_DIR "artifacts" -$PdbConverterToolVersion = "1.1.0-beta1-62316-01" +$PdbConverterToolVersion = "1.1.0-beta2-21075-01" function Locate-PdbConverterTool { - $pdbConverter = Join-Path -path $TP_PACKAGES_DIR -ChildPath "Pdb2Pdb\$PdbConverterToolVersion\tools\Pdb2Pdb.exe" + $pdbConverter = Join-Path -path $TP_PACKAGES_DIR -ChildPath "Microsoft.DiaSymReader.Pdb2Pdb\$PdbConverterToolVersion\tools\Pdb2Pdb.exe" - if (!(Test-Path -path $pdbConverter)) { + if (!(Test-Path -path $pdbConverter)) { throw "Unable to locate Pdb2Pdb converter exe in path '$pdbConverter'." } diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 9a6f5a19e8..b80ccd4bcd 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -812,6 +812,7 @@ function Create-NugetPackages Copy-Item (Join-Path $env:TP_PACKAGE_PROJ_DIR "Icon.png") $stagingDir -Force + if (-not (Test-Path $packageOutputDir)) { New-Item $packageOutputDir -type directory -Force } @@ -847,6 +848,9 @@ function Create-NugetPackages Copy-Item $tpNuspecDir\"_._" $stagingDir -Force Copy-Item $tpNuspecDir\..\"ThirdPartyNotices.txt" $stagingDir -Force + # Copy licenses folder + Copy-Item (Join-Path $env:TP_PACKAGE_PROJ_DIR "licenses") $stagingDir -Force -Recurse + #Copy Uap target, & props $testhostUapPackageDir = $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\Microsoft.TestPlatform.TestHost\$TPB_TargetFrameworkUap100") Copy-Item $tpNuspecDir\uap\"Microsoft.TestPlatform.TestHost.Uap.props" $testhostUapPackageDir\Microsoft.TestPlatform.TestHost.props -Force diff --git a/scripts/build.sh b/scripts/build.sh index e06fb9721b..829a4d8229 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -390,6 +390,7 @@ function create_package() cp "$TP_PACKAGE_NUSPEC_DIR/_._" $stagingDir cp "$TP_PACKAGE_NUSPEC_DIR/../ThirdPartyNotices.txt" $stagingDir cp "$TP_PACKAGE_NUSPEC_DIR/../Icon.png" $stagingDir + cp -r "$TP_PACKAGE_NUSPEC_DIR/../licenses" $stagingDir for i in ${projectFiles[@]}; do log "$dotnet pack --no-build $stagingDir/${i} -o $packageOutputDir -p:Version=$TPB_Version" \ diff --git a/scripts/verify-nupkgs.ps1 b/scripts/verify-nupkgs.ps1 index c660deb065..1ac89ac370 100644 --- a/scripts/verify-nupkgs.ps1 +++ b/scripts/verify-nupkgs.ps1 @@ -12,17 +12,17 @@ function Verify-Nuget-Packages($packageDirectory, $version) { Write-Log "Starting Verify-Nuget-Packages." $expectedNumOfFiles = @{ - "Microsoft.CodeCoverage" = 60; - "Microsoft.NET.Test.Sdk" = 26; - "Microsoft.TestPlatform" = 514; - "Microsoft.TestPlatform.Build" = 20; - "Microsoft.TestPlatform.CLI" = 380; - "Microsoft.TestPlatform.Extensions.TrxLogger" = 34; - "Microsoft.TestPlatform.ObjectModel" = 179; - "Microsoft.TestPlatform.AdapterUtilities" = 47; - "Microsoft.TestPlatform.Portable" = 569; - "Microsoft.TestPlatform.TestHost" = 213; - "Microsoft.TestPlatform.TranslationLayer" = 122; + "Microsoft.CodeCoverage" = 61; + "Microsoft.NET.Test.Sdk" = 27; + "Microsoft.TestPlatform" = 515; + "Microsoft.TestPlatform.Build" = 21; + "Microsoft.TestPlatform.CLI" = 381; + "Microsoft.TestPlatform.Extensions.TrxLogger" = 35; + "Microsoft.TestPlatform.ObjectModel" = 180; + "Microsoft.TestPlatform.AdapterUtilities" = 48; + "Microsoft.TestPlatform.Portable" = 570; + "Microsoft.TestPlatform.TestHost" = 214; + "Microsoft.TestPlatform.TranslationLayer" = 123; } $nugetPackages = Get-ChildItem -Filter "*$version*.nupkg" $packageDirectory | % { $_.FullName } diff --git a/src/package/external/external.csproj b/src/package/external/external.csproj index effc47856a..4627131052 100644 --- a/src/package/external/external.csproj +++ b/src/package/external/external.csproj @@ -45,8 +45,8 @@ 2.0.2 All - - 1.1.0-beta1-62316-01 + + 1.1.0-beta2-21075-01 All diff --git a/src/package/licenses/LICENSE_NET.txt b/src/package/licenses/LICENSE_NET.txt new file mode 100644 index 0000000000..5b03e9dce1 --- /dev/null +++ b/src/package/licenses/LICENSE_NET.txt @@ -0,0 +1,65 @@ +MICROSOFT SOFTWARE LICENSE TERMS + +MICROSOFT .NET LIBRARY + +These license terms are an agreement between you and Microsoft Corporation (or based on where you live, one of its affiliates). They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms. + +IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. + +1. INSTALLATION AND USE RIGHTS. +You may install and use any number of copies of the software to develop and test your applications. + +2. THIRD PARTY COMPONENTS. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software. +3. ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS. +a. DISTRIBUTABLE CODE. The software is comprised of Distributable Code. “Distributable Code” is code that you are permitted to distribute in applications you develop if you comply with the terms below. +i. Right to Use and Distribute. +· You may copy and distribute the object code form of the software. + +· Third Party Distribution. You may permit distributors of your applications to copy and distribute the Distributable Code as part of those applications. + +ii. Distribution Requirements. For any Distributable Code you distribute, you must +· use the Distributable Code in your applications and not as a standalone distribution; + +· require distributors and external end users to agree to terms that protect it at least as much as this agreement; and + +· indemnify, defend, and hold harmless Microsoft from any claims, including attorneys’ fees, related to the distribution or use of your applications, except to the extent that any claim is based solely on the unmodified Distributable Code. + +iii. Distribution Restrictions. You may not +· use Microsoft’s trademarks in your applications’ names or in a way that suggests your applications come from or are endorsed by Microsoft; or + +· modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An “Excluded License” is one that requires, as a condition of use, modification or distribution of code, that (i) it be disclosed or distributed in source code form; or (ii) others have the right to modify it. + +4. DATA. +a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the software documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with Microsoft’s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and its use from the software documentation and our privacy statement. Your use of the software operates as your consent to these practices. +b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at https://docs.microsoft.com/en-us/legal/gdpr. +5. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not +· work around any technical limitations in the software; + +· reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software; + +· remove, minimize, block or modify any notices of Microsoft or its suppliers in the software; + +· use the software in any way that is against the law; or + +· share, publish, rent or lease the software, provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party. + +6. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting. +7. SUPPORT SERVICES. Because this software is “as is,” we may not provide support services for it. +8. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services. +9. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply. +10. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you: +a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights. +b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software. +c) Germany and Austria. +(i) Warranty. The software will perform substantially as described in any Microsoft materials that accompany it. However, Microsoft gives no contractual guarantee in relation to the software. + +(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as in case of death or personal or physical injury, Microsoft is liable according to the statutory law. + +Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence +11. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +12. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. +This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law. + +It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state or country may not allow the exclusion or limitation of incidental, consequential or other damages. + + \ No newline at end of file diff --git a/src/package/licenses/LICENSE_VS.txt b/src/package/licenses/LICENSE_VS.txt new file mode 100644 index 0000000000..1db0151059 --- /dev/null +++ b/src/package/licenses/LICENSE_VS.txt @@ -0,0 +1,59 @@ +MICROSOFT SOFTWARE LICENSE TERMS + +MICROSOFT VISUAL STUDIO TEST PLATFORM + +These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms. + +IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. + +1. INSTALLATION AND USE RIGHTS. + +You may install and use any number of copies of the software. + +2. TERMS FOR SPECIFIC COMPONENTS. + +a. Third Party Components. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software. Even if such components are governed by other agreements, the disclaimers and the limitations on and exclusions of damages below also apply. + +3. DATA. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications and you should provide a copy of Microsoft’s privacy statement to your users. The Microsoft privacy statement is located here https://go.microsoft.com/fwlink/?LinkId=521839. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. + +4. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not + +· work around any technical limitations in the software; + +· reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software except, and only to the extent required by third party licensing terms governing the use of certain open source components that may be included in the software; + +· remove, minimize, block or modify any notices of Microsoft or its suppliers in the software; + +· use the software in any way that is against the law; or + +· share, publish, rent or lease the software, or provide the software as a stand-alone hosted as solution for others to use, or transfer the software or this agreement to any third party. + +5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting. + +6. SUPPORT SERVICES. Because this software is “as is,” we may not provide support services for it. + +7. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services. + +8. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply. + +9. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you: + +a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights. + +b. Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software. + +c. Germany and Austria. + +(i) Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software. + +(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law. + +Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence. + +10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + +11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. + +This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law. + +It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages. \ No newline at end of file diff --git a/src/package/nuspec/Microsoft.CodeCoverage.nuspec b/src/package/nuspec/Microsoft.CodeCoverage.nuspec index ac1e347e9c..2bd731e6e1 100644 --- a/src/package/nuspec/Microsoft.CodeCoverage.nuspec +++ b/src/package/nuspec/Microsoft.CodeCoverage.nuspec @@ -8,7 +8,7 @@ Microsoft true Microsoft.CodeCoverage package brings infra for collecting code coverage from vstest.console.exe and "dotnet test". - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -27,7 +27,7 @@ - + diff --git a/src/package/nuspec/Microsoft.NET.Test.Sdk.nuspec b/src/package/nuspec/Microsoft.NET.Test.Sdk.nuspec index a98d7a64eb..7727e08372 100644 --- a/src/package/nuspec/Microsoft.NET.Test.Sdk.nuspec +++ b/src/package/nuspec/Microsoft.NET.Test.Sdk.nuspec @@ -7,7 +7,7 @@ Microsoft Microsoft true - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png The MSbuild targets and properties for building .NET test projects. @@ -44,7 +44,7 @@ - + diff --git a/src/package/nuspec/Microsoft.TestPlatform.AdapterUtilities.nuspec b/src/package/nuspec/Microsoft.TestPlatform.AdapterUtilities.nuspec index 2dfbe5b36c..84b41b837e 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.AdapterUtilities.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.AdapterUtilities.nuspec @@ -10,7 +10,7 @@ Includes helpers for the Test Platform's modern functionality such as standardized fully qualified names and hierarchical test case names. - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -38,7 +38,7 @@ - + diff --git a/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec b/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec index 5daced586d..8c8b69365a 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec @@ -9,7 +9,7 @@ true This package contains a subset of binaries for the Visual Studio Test Platform (vstest). vstest provides a modern, cross platform testing engine that also powers the testing on .NET Core. Supports the following popular test frameworks - MSTest v2, xUnit and Nunit with support for extensibility. Visit https://github.com/microsoft/vstest to know more about vstest platform. For running tests based on the MSTest v1 framework, .orderedtest, .webtest and .generictest please use Microsoft.TestPlatform package. This package contains a subset of binaries for the Visual Studio Test Platform (vstest). vstest provides a modern, cross platform testing engine that also powers the testing on .NET Core. Supports the following popular test frameworks - MSTest v2, xUnit and Nunit with support for extensibility. - https://www.visualstudio.com/microsoft-visual-studio-test-platform + LICENSE_VS.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -22,7 +22,7 @@ - + diff --git a/src/package/nuspec/Microsoft.TestPlatform.nuspec b/src/package/nuspec/Microsoft.TestPlatform.nuspec index 1e0e3b6103..40d8431f98 100644 --- a/src/package/nuspec/Microsoft.TestPlatform.nuspec +++ b/src/package/nuspec/Microsoft.TestPlatform.nuspec @@ -9,7 +9,7 @@ true This package contains the full set of binaries for the Visual Studio Test Platform (vstest). It provides a modern, cross platform testing engine that powers the testing on .NET Core as well. It integrates with popular test frameworks like MSTest(v1 and v2), xUnit and Nunit with support for extensibility. The package supports running Coded UI tests. While running Coded UI tests, you must ensure that the package version matches the major version of Visual Studio used to build the test binaries. For example, if your Coded UI test project was built using Visual Studio 2019 (version 16.x), you must use test platform version 16.x. Coded UI test is deprecated (https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-preview#test-tools) and Visual Studio 2019 (Test Platform version 16.x) will be the last version with Coded UI test functionality. Visit https://github.com/microsoft/vstest to know more about vstest platform. This package contains the full set of binaries for the Visual Studio Test Platform (vstest). It provides a modern, cross platform testing engine that powers the testing on .NET Core as well. It integrates with popular test frameworks like MSTest(v1 and v2), xUnit and Nunit with support for extensibility. - https://www.visualstudio.com/microsoft-visual-studio-test-platform + LICENSE_VS.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -22,7 +22,7 @@ - + diff --git a/src/package/nuspec/TestPlatform.Build.nuspec b/src/package/nuspec/TestPlatform.Build.nuspec index 79dc3c3341..3808b2965f 100644 --- a/src/package/nuspec/TestPlatform.Build.nuspec +++ b/src/package/nuspec/TestPlatform.Build.nuspec @@ -8,7 +8,7 @@ Microsoft true Build tasks and targets for running tests with Test Platform - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -25,7 +25,7 @@ - + diff --git a/src/package/nuspec/TestPlatform.CLI.nuspec b/src/package/nuspec/TestPlatform.CLI.nuspec index 57a9d36ade..0e72bf5885 100644 --- a/src/package/nuspec/TestPlatform.CLI.nuspec +++ b/src/package/nuspec/TestPlatform.CLI.nuspec @@ -8,7 +8,7 @@ Microsoft true The cross platform Microsoft Test Platform. - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -25,7 +25,7 @@ - + diff --git a/src/package/nuspec/TestPlatform.Extensions.TrxLogger.nuspec b/src/package/nuspec/TestPlatform.Extensions.TrxLogger.nuspec index 94d86b5633..802ce1eba2 100644 --- a/src/package/nuspec/TestPlatform.Extensions.TrxLogger.nuspec +++ b/src/package/nuspec/TestPlatform.Extensions.TrxLogger.nuspec @@ -8,7 +8,7 @@ Microsoft true C# SDK for the test platform protocol. This SDK can be used in IDE or Editors to use test platform for discovery and execution of tests. - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -40,7 +40,7 @@ - + diff --git a/src/package/nuspec/TestPlatform.ObjectModel.nuspec b/src/package/nuspec/TestPlatform.ObjectModel.nuspec index e76d1096e8..80d194f2e8 100644 --- a/src/package/nuspec/TestPlatform.ObjectModel.nuspec +++ b/src/package/nuspec/TestPlatform.ObjectModel.nuspec @@ -8,7 +8,7 @@ Microsoft true The Microsoft Test Platform Object Model. - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -82,8 +82,8 @@ - - + + diff --git a/src/package/nuspec/TestPlatform.TestHost.nuspec b/src/package/nuspec/TestPlatform.TestHost.nuspec index 15839c44cc..86a4edea10 100644 --- a/src/package/nuspec/TestPlatform.TestHost.nuspec +++ b/src/package/nuspec/TestPlatform.TestHost.nuspec @@ -8,7 +8,7 @@ Microsoft true Testplatform host executes the test using specified adapter. - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -50,7 +50,7 @@ - + diff --git a/src/package/nuspec/TestPlatform.TranslationLayer.nuspec b/src/package/nuspec/TestPlatform.TranslationLayer.nuspec index 62d30c85e4..420efde67c 100644 --- a/src/package/nuspec/TestPlatform.TranslationLayer.nuspec +++ b/src/package/nuspec/TestPlatform.TranslationLayer.nuspec @@ -8,7 +8,7 @@ Microsoft true C# SDK for the test platform protocol. This SDK can be used in IDE or Editors to use test platform for discovery and execution of tests. - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 Icon.png https://github.com/microsoft/vstest/ @@ -37,7 +37,7 @@ - + diff --git a/test/TestAssets/CPPSimpleTestProject/Microsoft.TestPlatform.Asset.NativeCPP.nuspec b/test/TestAssets/CPPSimpleTestProject/Microsoft.TestPlatform.Asset.NativeCPP.nuspec index 1aa97e694e..b2df3444ec 100644 --- a/test/TestAssets/CPPSimpleTestProject/Microsoft.TestPlatform.Asset.NativeCPP.nuspec +++ b/test/TestAssets/CPPSimpleTestProject/Microsoft.TestPlatform.Asset.NativeCPP.nuspec @@ -7,7 +7,7 @@ Microsoft Microsoft false - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 MSDia typelib for reading debug symbols from managed code. Copyright © Microsoft Corporation @@ -17,6 +17,7 @@ + diff --git a/test/TestAssets/QualityToolsAssets/Microsoft.TestPlatform.QTools.Assets.nuspec b/test/TestAssets/QualityToolsAssets/Microsoft.TestPlatform.QTools.Assets.nuspec index 55ac1c4235..1090df2b39 100644 --- a/test/TestAssets/QualityToolsAssets/Microsoft.TestPlatform.QTools.Assets.nuspec +++ b/test/TestAssets/QualityToolsAssets/Microsoft.TestPlatform.QTools.Assets.nuspec @@ -7,7 +7,7 @@ Microsoft Microsoft false - http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm + LICENSE_NET.txt http://go.microsoft.com/fwlink/?LinkID=288859 MSDia typelib for reading debug symbols from managed code. Copyright © Microsoft Corporation @@ -17,6 +17,7 @@ +