Skip to content

Commit 7909f50

Browse files
DataCollector search in output directory (#2015)
* DataCollector Search in output directory
1 parent 06cf5cf commit 7909f50

File tree

3 files changed

+88
-34
lines changed

3 files changed

+88
-34
lines changed

src/Microsoft.TestPlatform.CommunicationUtilities/DataCollectionRequestHandler.cs

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.DataCollect
2525
using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
2626
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
2727
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;
28-
28+
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;
2929
using CommunicationUtilitiesResources = Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Resources.Resources;
3030
using CoreUtilitiesConstants = Microsoft.VisualStudio.TestPlatform.CoreUtilities.Constants;
3131

@@ -48,6 +48,8 @@ internal class DataCollectionRequestHandler : IDataCollectionRequestHandler, IDi
4848

4949
private IDataSerializer dataSerializer;
5050

51+
private IFileHelper fileHelper;
52+
5153
/// <summary>
5254
/// Use to cancel data collection test case events monitoring if test run is cancelled.
5355
/// </summary>
@@ -65,7 +67,8 @@ protected DataCollectionRequestHandler(IMessageSink messageSink)
6567
messageSink,
6668
DataCollectionManager.Create(messageSink),
6769
new DataCollectionTestCaseEventHandler(),
68-
JsonDataSerializer.Instance)
70+
JsonDataSerializer.Instance,
71+
new FileHelper())
6972
{
7073
this.messageSink = messageSink;
7174
}
@@ -88,19 +91,24 @@ protected DataCollectionRequestHandler(IMessageSink messageSink)
8891
/// <param name="dataSerializer">
8992
/// Serializer for serialization and deserialization of the messages.
9093
/// </param>
94+
/// <param name="fileHelper">
95+
/// File Helper
96+
/// </param>
9197
protected DataCollectionRequestHandler(
9298
ICommunicationManager communicationManager,
9399
IMessageSink messageSink,
94100
IDataCollectionManager dataCollectionManager,
95101
IDataCollectionTestCaseEventHandler dataCollectionTestCaseEventHandler,
96-
IDataSerializer dataSerializer)
102+
IDataSerializer dataSerializer,
103+
IFileHelper fileHelper)
97104
{
98105
this.communicationManager = communicationManager;
99106
this.messageSink = messageSink;
100107
this.dataCollectionManager = dataCollectionManager;
101108
this.dataSerializer = dataSerializer;
102109
this.dataCollectionTestCaseEventHandler = dataCollectionTestCaseEventHandler;
103110
this.cancellationTokenSource = new CancellationTokenSource();
111+
this.fileHelper = fileHelper;
104112
}
105113

106114
/// <summary>
@@ -137,7 +145,8 @@ public static DataCollectionRequestHandler Create(
137145
messageSink,
138146
DataCollectionManager.Create(messageSink),
139147
new DataCollectionTestCaseEventHandler(),
140-
JsonDataSerializer.Instance);
148+
JsonDataSerializer.Instance,
149+
new FileHelper());
141150
}
142151
}
143152
}
@@ -228,40 +237,49 @@ public void Close()
228237
/// <summary>
229238
/// Update the test adapter paths provided through run settings to be used by the test plugin cache.
230239
/// </summary>
231-
/// <param name="runSettings">
232-
/// The run Settings.
240+
/// <param name="payload">
241+
/// The before test run start payload
233242
/// </param>
234-
private void AddExtensionAssemblies(string runSettings)
243+
private void AddExtensionAssemblies(BeforeTestRunStartPayload payload)
235244
{
236245
try
237246
{
238-
IEnumerable<string> customTestAdaptersPaths = RunSettingsUtilities.GetTestAdaptersPaths(runSettings);
247+
var customTestAdaptersPaths = RunSettingsUtilities.GetTestAdaptersPaths(payload.SettingsXml);
248+
249+
// In case of dotnet vstest with code coverage, data collector needs to be picked up from publish folder.
250+
// Therefore, adding source dll folders to search datacollectors in these.
251+
var datacollectorSearchPaths = new HashSet<string>();
252+
foreach (var source in payload.Sources)
253+
{
254+
datacollectorSearchPaths.Add(Path.GetDirectoryName(source));
255+
}
256+
239257
if (customTestAdaptersPaths != null)
240258
{
241-
var fileHelper = new FileHelper();
259+
datacollectorSearchPaths.UnionWith(customTestAdaptersPaths);
260+
}
242261

243-
List<string> extensionAssemblies = new List<string>();
244-
foreach (var customTestAdaptersPath in customTestAdaptersPaths)
262+
List<string> extensionAssemblies = new List<string>();
263+
foreach (var datacollectorSearchPath in datacollectorSearchPaths)
264+
{
265+
var adapterPath =
266+
Path.GetFullPath(Environment.ExpandEnvironmentVariables(datacollectorSearchPath));
267+
if (!this.fileHelper.DirectoryExists(adapterPath))
245268
{
246-
var adapterPath =
247-
Path.GetFullPath(Environment.ExpandEnvironmentVariables(customTestAdaptersPath));
248-
if (!fileHelper.DirectoryExists(adapterPath))
249-
{
250-
EqtTrace.Warning(string.Format("AdapterPath Not Found:", adapterPath));
251-
continue;
252-
}
253-
254-
extensionAssemblies.AddRange(
255-
fileHelper.EnumerateFiles(
256-
adapterPath,
257-
SearchOption.AllDirectories,
258-
TestPlatformConstants.DataCollectorEndsWithPattern));
269+
EqtTrace.Warning(string.Format("AdapterPath Not Found:", adapterPath));
270+
continue;
259271
}
260272

261-
if (extensionAssemblies.Count > 0)
262-
{
263-
TestPluginCache.Instance.UpdateExtensions(extensionAssemblies, skipExtensionFilters: false);
264-
}
273+
extensionAssemblies.AddRange(
274+
this.fileHelper.EnumerateFiles(
275+
adapterPath,
276+
SearchOption.AllDirectories,
277+
TestPlatformConstants.DataCollectorEndsWithPattern));
278+
}
279+
280+
if (extensionAssemblies.Count > 0)
281+
{
282+
TestPluginCache.Instance.UpdateExtensions(extensionAssemblies, skipExtensionFilters: false);
265283
}
266284
}
267285
catch (Exception e)
@@ -278,7 +296,7 @@ private void HandleBeforeTestRunStart(Message message)
278296
{
279297
// Initialize datacollectors and get enviornment variables.
280298
var payload = this.dataSerializer.DeserializePayload<BeforeTestRunStartPayload>(message);
281-
this.AddExtensionAssemblies(payload.SettingsXml);
299+
this.AddExtensionAssemblies(payload);
282300

283301
var envVariables = this.dataCollectionManager.InitializeDataCollectors(payload.SettingsXml);
284302

test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/DataCollectionRequestHandlerTests.cs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,25 @@
44
namespace Microsoft.TestPlatform.CommunicationUtilities.UnitTests
55
{
66
using System;
7-
using System.Collections;
87
using System.Collections.Generic;
98
using System.Collections.ObjectModel;
10-
using System.Globalization;
9+
using System.IO;
1110
using System.Linq;
1211
using System.Net;
1312

1413
using Microsoft.TestPlatform.CommunicationUtilities.UnitTests.TestDoubles;
1514
using Microsoft.VisualStudio.TestPlatform.Common.DataCollection;
1615
using Microsoft.VisualStudio.TestPlatform.Common.DataCollector.Interfaces;
16+
using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework;
1717
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities;
1818
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.DataCollection;
19+
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.DataCollection.Interfaces;
1920
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces;
2021
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel;
2122
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
2223
using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
2324
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
25+
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;
2426
using Microsoft.VisualStudio.TestTools.UnitTesting;
2527

2628
using Moq;
@@ -39,6 +41,7 @@ public class DataCollectionRequestHandlerTests
3941
private Mock<IDataCollectionTestCaseEventHandler> mockDataCollectionTestCaseEventHandler;
4042
private TestableDataCollectionRequestHandler requestHandler;
4143
private Mock<IDataSerializer> mockDataSerializer;
44+
private Mock<IFileHelper> mockFileHelper;
4245
private Message afterTestRunEnd = new Message() { MessageType = MessageType.AfterTestRunEnd, Payload = "false" };
4346
private Message beforeTestRunStart = new Message()
4447
{
@@ -54,7 +57,8 @@ public DataCollectionRequestHandlerTests()
5457
this.mockDataSerializer = new Mock<IDataSerializer>();
5558
this.mockDataCollectionTestCaseEventHandler = new Mock<IDataCollectionTestCaseEventHandler>();
5659
this.mockDataCollectionTestCaseEventHandler.Setup(x => x.WaitForRequestHandlerConnection(It.IsAny<int>())).Returns(true);
57-
this.requestHandler = new TestableDataCollectionRequestHandler(this.mockCommunicationManager.Object, this.mockMessageSink.Object, this.mockDataCollectionManager.Object, this.mockDataCollectionTestCaseEventHandler.Object, this.mockDataSerializer.Object);
60+
this.mockFileHelper = new Mock<IFileHelper>();
61+
this.requestHandler = new TestableDataCollectionRequestHandler(this.mockCommunicationManager.Object, this.mockMessageSink.Object, this.mockDataCollectionManager.Object, this.mockDataCollectionTestCaseEventHandler.Object, this.mockDataSerializer.Object, this.mockFileHelper.Object);
5862

5963
this.mockCommunicationManager.SetupSequence(x => x.ReceiveMessage()).Returns(this.beforeTestRunStart).Returns(this.afterTestRunEnd);
6064

@@ -226,6 +230,34 @@ public void ProcessRequestsShouldDisposeDataCollectorsOnAfterTestRunEnd()
226230
this.mockDataCollectionManager.Verify(x => x.Dispose());
227231
}
228232

233+
[TestMethod]
234+
public void ProcessRequestsShouldAddSourceDirectoryToTestPluginCache()
235+
{
236+
var testHostLaunchedPayload = new TestHostLaunchedPayload();
237+
testHostLaunchedPayload.ProcessId = 1234;
238+
239+
string runSettings = "<RunSettings><RunConfiguration><TestAdaptersPaths>d:\\users;f:\\users</TestAdaptersPaths></RunConfiguration></RunSettings>";
240+
241+
this.mockCommunicationManager.SetupSequence(x => x.ReceiveMessage()).Returns(this.beforeTestRunStart)
242+
.Returns(new Message() { MessageType = MessageType.TestHostLaunched, Payload = JToken.FromObject(testHostLaunchedPayload) })
243+
.Returns(this.afterTestRunEnd);
244+
245+
this.mockDataCollectionManager.Setup(x => x.SessionStarted(It.IsAny<SessionStartEventArgs>())).Returns(true);
246+
this.mockDataCollectionManager.Setup(x => x.TestHostLaunched(It.IsAny<int>()));
247+
this.mockDataSerializer.Setup(x => x.DeserializePayload<TestHostLaunchedPayload>(It.Is<Message>(y => y.MessageType == MessageType.TestHostLaunched)))
248+
.Returns(testHostLaunchedPayload);
249+
var beforeTestRunSTartPayload = new BeforeTestRunStartPayload { SettingsXml = runSettings, Sources = new List<string> { @"E:\dir1\test1.dll", @"E:\dir2\test2.dll", @"E:\dir1\test2.dll" } };
250+
this.mockDataSerializer.Setup(x => x.DeserializePayload<BeforeTestRunStartPayload>(It.Is<Message>(y => y.MessageType == MessageType.BeforeTestRunStart)))
251+
.Returns(beforeTestRunSTartPayload);
252+
this.mockFileHelper.Setup(x => x.DirectoryExists(@"E:\dir1")).Returns(true);
253+
this.mockFileHelper.Setup(x => x.EnumerateFiles("E:\\dir1", SearchOption.AllDirectories, @"Collector.dll")).Returns(new List<string> { @"E:\dir1\abc.datacollector.dll" });
254+
255+
this.requestHandler.ProcessRequests();
256+
257+
this.mockFileHelper.Verify(x => x.EnumerateFiles("E:\\dir1", SearchOption.AllDirectories, @"Collector.dll"), Times.Once);
258+
Assert.IsTrue(TestPluginCache.Instance.GetExtensionPaths(@"Collector.dll").Contains(@"E:\dir1\abc.datacollector.dll"));
259+
}
260+
229261
[TestMethod]
230262
public void ProcessRequestsShouldThrowExceptionIfThrownByCommunicationManager()
231263
{

test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/TestDoubles/TestableDataCollectionRequestHandler.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ namespace Microsoft.TestPlatform.CommunicationUtilities.UnitTests.TestDoubles
66
using Microsoft.VisualStudio.TestPlatform.Common.DataCollector.Interfaces;
77
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.DataCollection;
88
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces;
9+
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;
910

11+
/// <summary>
12+
/// Testable class for DataCollectionRequestHandler since all constructors of DataCollectionRequestHandler are protected.
13+
/// </summary>
1014
internal class TestableDataCollectionRequestHandler : DataCollectionRequestHandler
1115
{
12-
public TestableDataCollectionRequestHandler(ICommunicationManager communicationManager, IMessageSink messageSink, IDataCollectionManager dataCollectionManager, IDataCollectionTestCaseEventHandler dataCollectionTestCaseEventHandler, IDataSerializer dataSerializer)
13-
: base(communicationManager, messageSink, dataCollectionManager, dataCollectionTestCaseEventHandler, dataSerializer)
16+
public TestableDataCollectionRequestHandler(ICommunicationManager communicationManager, IMessageSink messageSink, IDataCollectionManager dataCollectionManager, IDataCollectionTestCaseEventHandler dataCollectionTestCaseEventHandler, IDataSerializer dataSerializer, IFileHelper fIleHelper)
17+
: base(communicationManager, messageSink, dataCollectionManager, dataCollectionTestCaseEventHandler, dataSerializer, fIleHelper)
1418
{
1519
}
1620
}

0 commit comments

Comments
 (0)