From 7909f509be5a979620d8e164be39a7a20dddea59 Mon Sep 17 00:00:00 2001 From: Vagisha Nidhi Date: Mon, 13 May 2019 20:50:52 +0530 Subject: [PATCH] DataCollector search in output directory (#2015) * DataCollector Search in output directory --- .../DataCollectionRequestHandler.cs | 76 ++++++++++++------- .../DataCollectionRequestHandlerTests.cs | 38 +++++++++- .../TestableDataCollectionRequestHandler.cs | 8 +- 3 files changed, 88 insertions(+), 34 deletions(-) diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/DataCollectionRequestHandler.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/DataCollectionRequestHandler.cs index 62b1c088b1..80508b75dd 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/DataCollectionRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/DataCollectionRequestHandler.cs @@ -25,7 +25,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.DataCollect using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; - + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; using CommunicationUtilitiesResources = Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Resources.Resources; using CoreUtilitiesConstants = Microsoft.VisualStudio.TestPlatform.CoreUtilities.Constants; @@ -48,6 +48,8 @@ internal class DataCollectionRequestHandler : IDataCollectionRequestHandler, IDi private IDataSerializer dataSerializer; + private IFileHelper fileHelper; + /// /// Use to cancel data collection test case events monitoring if test run is cancelled. /// @@ -65,7 +67,8 @@ protected DataCollectionRequestHandler(IMessageSink messageSink) messageSink, DataCollectionManager.Create(messageSink), new DataCollectionTestCaseEventHandler(), - JsonDataSerializer.Instance) + JsonDataSerializer.Instance, + new FileHelper()) { this.messageSink = messageSink; } @@ -88,12 +91,16 @@ protected DataCollectionRequestHandler(IMessageSink messageSink) /// /// Serializer for serialization and deserialization of the messages. /// + /// + /// File Helper + /// protected DataCollectionRequestHandler( ICommunicationManager communicationManager, IMessageSink messageSink, IDataCollectionManager dataCollectionManager, IDataCollectionTestCaseEventHandler dataCollectionTestCaseEventHandler, - IDataSerializer dataSerializer) + IDataSerializer dataSerializer, + IFileHelper fileHelper) { this.communicationManager = communicationManager; this.messageSink = messageSink; @@ -101,6 +108,7 @@ protected DataCollectionRequestHandler(IMessageSink messageSink) this.dataSerializer = dataSerializer; this.dataCollectionTestCaseEventHandler = dataCollectionTestCaseEventHandler; this.cancellationTokenSource = new CancellationTokenSource(); + this.fileHelper = fileHelper; } /// @@ -137,7 +145,8 @@ protected DataCollectionRequestHandler(IMessageSink messageSink) messageSink, DataCollectionManager.Create(messageSink), new DataCollectionTestCaseEventHandler(), - JsonDataSerializer.Instance); + JsonDataSerializer.Instance, + new FileHelper()); } } } @@ -228,40 +237,49 @@ public void Close() /// /// Update the test adapter paths provided through run settings to be used by the test plugin cache. /// - /// - /// The run Settings. + /// + /// The before test run start payload /// - private void AddExtensionAssemblies(string runSettings) + private void AddExtensionAssemblies(BeforeTestRunStartPayload payload) { try { - IEnumerable customTestAdaptersPaths = RunSettingsUtilities.GetTestAdaptersPaths(runSettings); + var customTestAdaptersPaths = RunSettingsUtilities.GetTestAdaptersPaths(payload.SettingsXml); + + // In case of dotnet vstest with code coverage, data collector needs to be picked up from publish folder. + // Therefore, adding source dll folders to search datacollectors in these. + var datacollectorSearchPaths = new HashSet(); + foreach (var source in payload.Sources) + { + datacollectorSearchPaths.Add(Path.GetDirectoryName(source)); + } + if (customTestAdaptersPaths != null) { - var fileHelper = new FileHelper(); + datacollectorSearchPaths.UnionWith(customTestAdaptersPaths); + } - List extensionAssemblies = new List(); - foreach (var customTestAdaptersPath in customTestAdaptersPaths) + List extensionAssemblies = new List(); + foreach (var datacollectorSearchPath in datacollectorSearchPaths) + { + var adapterPath = + Path.GetFullPath(Environment.ExpandEnvironmentVariables(datacollectorSearchPath)); + if (!this.fileHelper.DirectoryExists(adapterPath)) { - var adapterPath = - Path.GetFullPath(Environment.ExpandEnvironmentVariables(customTestAdaptersPath)); - if (!fileHelper.DirectoryExists(adapterPath)) - { - EqtTrace.Warning(string.Format("AdapterPath Not Found:", adapterPath)); - continue; - } - - extensionAssemblies.AddRange( - fileHelper.EnumerateFiles( - adapterPath, - SearchOption.AllDirectories, - TestPlatformConstants.DataCollectorEndsWithPattern)); + EqtTrace.Warning(string.Format("AdapterPath Not Found:", adapterPath)); + continue; } - if (extensionAssemblies.Count > 0) - { - TestPluginCache.Instance.UpdateExtensions(extensionAssemblies, skipExtensionFilters: false); - } + extensionAssemblies.AddRange( + this.fileHelper.EnumerateFiles( + adapterPath, + SearchOption.AllDirectories, + TestPlatformConstants.DataCollectorEndsWithPattern)); + } + + if (extensionAssemblies.Count > 0) + { + TestPluginCache.Instance.UpdateExtensions(extensionAssemblies, skipExtensionFilters: false); } } catch (Exception e) @@ -278,7 +296,7 @@ private void HandleBeforeTestRunStart(Message message) { // Initialize datacollectors and get enviornment variables. var payload = this.dataSerializer.DeserializePayload(message); - this.AddExtensionAssemblies(payload.SettingsXml); + this.AddExtensionAssemblies(payload); var envVariables = this.dataCollectionManager.InitializeDataCollectors(payload.SettingsXml); diff --git a/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/DataCollectionRequestHandlerTests.cs b/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/DataCollectionRequestHandlerTests.cs index b70096adb2..d8855489a8 100644 --- a/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/DataCollectionRequestHandlerTests.cs +++ b/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/DataCollectionRequestHandlerTests.cs @@ -4,23 +4,25 @@ namespace Microsoft.TestPlatform.CommunicationUtilities.UnitTests { using System; - using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; - using System.Globalization; + using System.IO; using System.Linq; using System.Net; using Microsoft.TestPlatform.CommunicationUtilities.UnitTests.TestDoubles; using Microsoft.VisualStudio.TestPlatform.Common.DataCollection; using Microsoft.VisualStudio.TestPlatform.Common.DataCollector.Interfaces; + using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.DataCollection; + using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.DataCollection.Interfaces; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -39,6 +41,7 @@ public class DataCollectionRequestHandlerTests private Mock mockDataCollectionTestCaseEventHandler; private TestableDataCollectionRequestHandler requestHandler; private Mock mockDataSerializer; + private Mock mockFileHelper; private Message afterTestRunEnd = new Message() { MessageType = MessageType.AfterTestRunEnd, Payload = "false" }; private Message beforeTestRunStart = new Message() { @@ -54,7 +57,8 @@ public DataCollectionRequestHandlerTests() this.mockDataSerializer = new Mock(); this.mockDataCollectionTestCaseEventHandler = new Mock(); this.mockDataCollectionTestCaseEventHandler.Setup(x => x.WaitForRequestHandlerConnection(It.IsAny())).Returns(true); - this.requestHandler = new TestableDataCollectionRequestHandler(this.mockCommunicationManager.Object, this.mockMessageSink.Object, this.mockDataCollectionManager.Object, this.mockDataCollectionTestCaseEventHandler.Object, this.mockDataSerializer.Object); + this.mockFileHelper = new Mock(); + this.requestHandler = new TestableDataCollectionRequestHandler(this.mockCommunicationManager.Object, this.mockMessageSink.Object, this.mockDataCollectionManager.Object, this.mockDataCollectionTestCaseEventHandler.Object, this.mockDataSerializer.Object, this.mockFileHelper.Object); this.mockCommunicationManager.SetupSequence(x => x.ReceiveMessage()).Returns(this.beforeTestRunStart).Returns(this.afterTestRunEnd); @@ -226,6 +230,34 @@ public void ProcessRequestsShouldDisposeDataCollectorsOnAfterTestRunEnd() this.mockDataCollectionManager.Verify(x => x.Dispose()); } + [TestMethod] + public void ProcessRequestsShouldAddSourceDirectoryToTestPluginCache() + { + var testHostLaunchedPayload = new TestHostLaunchedPayload(); + testHostLaunchedPayload.ProcessId = 1234; + + string runSettings = "d:\\users;f:\\users"; + + this.mockCommunicationManager.SetupSequence(x => x.ReceiveMessage()).Returns(this.beforeTestRunStart) + .Returns(new Message() { MessageType = MessageType.TestHostLaunched, Payload = JToken.FromObject(testHostLaunchedPayload) }) + .Returns(this.afterTestRunEnd); + + this.mockDataCollectionManager.Setup(x => x.SessionStarted(It.IsAny())).Returns(true); + this.mockDataCollectionManager.Setup(x => x.TestHostLaunched(It.IsAny())); + this.mockDataSerializer.Setup(x => x.DeserializePayload(It.Is(y => y.MessageType == MessageType.TestHostLaunched))) + .Returns(testHostLaunchedPayload); + var beforeTestRunSTartPayload = new BeforeTestRunStartPayload { SettingsXml = runSettings, Sources = new List { @"E:\dir1\test1.dll", @"E:\dir2\test2.dll", @"E:\dir1\test2.dll" } }; + this.mockDataSerializer.Setup(x => x.DeserializePayload(It.Is(y => y.MessageType == MessageType.BeforeTestRunStart))) + .Returns(beforeTestRunSTartPayload); + this.mockFileHelper.Setup(x => x.DirectoryExists(@"E:\dir1")).Returns(true); + this.mockFileHelper.Setup(x => x.EnumerateFiles("E:\\dir1", SearchOption.AllDirectories, @"Collector.dll")).Returns(new List { @"E:\dir1\abc.datacollector.dll" }); + + this.requestHandler.ProcessRequests(); + + this.mockFileHelper.Verify(x => x.EnumerateFiles("E:\\dir1", SearchOption.AllDirectories, @"Collector.dll"), Times.Once); + Assert.IsTrue(TestPluginCache.Instance.GetExtensionPaths(@"Collector.dll").Contains(@"E:\dir1\abc.datacollector.dll")); + } + [TestMethod] public void ProcessRequestsShouldThrowExceptionIfThrownByCommunicationManager() { diff --git a/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/TestDoubles/TestableDataCollectionRequestHandler.cs b/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/TestDoubles/TestableDataCollectionRequestHandler.cs index 861f602f1f..375272f712 100644 --- a/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/TestDoubles/TestableDataCollectionRequestHandler.cs +++ b/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/TestDoubles/TestableDataCollectionRequestHandler.cs @@ -6,11 +6,15 @@ namespace Microsoft.TestPlatform.CommunicationUtilities.UnitTests.TestDoubles using Microsoft.VisualStudio.TestPlatform.Common.DataCollector.Interfaces; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.DataCollection; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; + /// + /// Testable class for DataCollectionRequestHandler since all constructors of DataCollectionRequestHandler are protected. + /// internal class TestableDataCollectionRequestHandler : DataCollectionRequestHandler { - public TestableDataCollectionRequestHandler(ICommunicationManager communicationManager, IMessageSink messageSink, IDataCollectionManager dataCollectionManager, IDataCollectionTestCaseEventHandler dataCollectionTestCaseEventHandler, IDataSerializer dataSerializer) - : base(communicationManager, messageSink, dataCollectionManager, dataCollectionTestCaseEventHandler, dataSerializer) + public TestableDataCollectionRequestHandler(ICommunicationManager communicationManager, IMessageSink messageSink, IDataCollectionManager dataCollectionManager, IDataCollectionTestCaseEventHandler dataCollectionTestCaseEventHandler, IDataSerializer dataSerializer, IFileHelper fIleHelper) + : base(communicationManager, messageSink, dataCollectionManager, dataCollectionTestCaseEventHandler, dataSerializer, fIleHelper) { } }