Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Fakes Datacollector settings to be added in design mode #2586

Merged
merged 6 commits into from
Oct 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions src/Microsoft.TestPlatform.Common/Utilities/FakesUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.Utilities
using System.IO;
using System.Reflection;
using System.Xml;

using System.Xml.XPath;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;

Expand Down Expand Up @@ -104,12 +104,6 @@ private static bool TryAddFakesDataCollectorSettings(
IEnumerable<string> sources,
FrameworkVersion framework)
{
// If user provided fakes settings don't do anything
if (XmlRunSettingsUtilities.ContainsDataCollector(runSettings.CreateNavigator(), FakesMetadata.DataCollectorUri))
{
return false;
}

// A new Fakes Congigurator API makes the decision to add the right datacollector uri to the configuration
// There now exist two data collector URIs to support two different scenarios. The new scenario involves
// using the CLRIE profiler, and the old involves using the Intellitrace profiler (which isn't supported in
Expand All @@ -120,19 +114,42 @@ private static bool TryAddFakesDataCollectorSettings(
{
var sourceTFMMap = CreateDictionary(sources, framework);
var fakesSettings = crossPlatformConfigurator(sourceTFMMap);

// if no fakes, return settings unchanged
if (fakesSettings == null)
{
return false;
}

XmlRunSettingsUtilities.InsertDataCollectorsNode(runSettings.CreateNavigator(), fakesSettings);
InsertOrReplaceFakesDataCollectorNode(runSettings, fakesSettings);
return true;
}

return AddFallbackFakesSettings(runSettings, sources, framework);
}

internal static void InsertOrReplaceFakesDataCollectorNode(XmlDocument runSettings, DataCollectorSettings settings)
{
// override current settings
var navigator = runSettings.CreateNavigator();
var nodes = navigator.Select("/RunSettings/DataCollectionRunSettings/DataCollectors/DataCollector");

foreach (XPathNavigator dataCollectorNavigator in nodes)
{
var uri = dataCollectorNavigator.GetAttribute("uri", string.Empty);
// We assume that only one uri can exist in a given runsettings
if (string.Equals(FakesMetadata.DataCollectorUriV1, uri, StringComparison.OrdinalIgnoreCase) ||
string.Equals(FakesMetadata.DataCollectorUriV2, uri, StringComparison.OrdinalIgnoreCase))
{
dataCollectorNavigator.ReplaceSelf(settings.ToXml().CreateNavigator());
return;
}
}

// insert new node
XmlRunSettingsUtilities.InsertDataCollectorsNode(runSettings.CreateNavigator(), settings);
}

private static IDictionary<string, FrameworkVersion> CreateDictionary(IEnumerable<string> sources, FrameworkVersion framework)
{
var dict = new Dictionary<string, FrameworkVersion>();
Expand Down Expand Up @@ -275,7 +292,7 @@ private static DataCollectorSettings CreateFakesDataCollectorSettings()
AssemblyQualifiedName = FakesMetadata.DataCollectorAssemblyQualifiedName,
FriendlyName = FakesMetadata.FriendlyName,
IsEnabled = true,
Uri = new Uri(FakesMetadata.DataCollectorUri)
Uri = new Uri(FakesMetadata.DataCollectorUriV1)
};
return settings;
}
Expand All @@ -290,7 +307,12 @@ internal static class FakesMetadata
/// <summary>
/// Gets the URI of the data collector
/// </summary>
public const string DataCollectorUri = "datacollector://microsoft/unittestisolation/1.0";
public const string DataCollectorUriV1 = "datacollector://microsoft/unittestisolation/1.0";

/// <summary>
/// Gets the URI of the data collector
/// </summary>
public const string DataCollectorUriV2 = "datacollector://microsoft/unittestisolation/2.0";

/// <summary>
/// Gets the assembly qualified name of the data collector type
Expand Down
3 changes: 2 additions & 1 deletion src/vstest.console/CommandLine/GenerateFakesUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public static class GenerateFakesUtilities
internal static void GenerateFakesSettings(CommandLineOptions commandLineOptions, IEnumerable<string> sources, ref string runSettingsXml)
{
// dynamically compute the fakes datacollector settings
if (!commandLineOptions.DisableAutoFakes)
// This runs with or without design mode.
if (commandLineOptions == null || !commandLineOptions.DisableAutoFakes)
vritant24 marked this conversation as resolved.
Show resolved Hide resolved
{
runSettingsXml = FakesUtilities.GenerateFakesSettingsForRunConfiguration(sources.ToArray(), runSettingsXml);
}
Expand Down
37 changes: 22 additions & 15 deletions src/vstest.console/TestPlatformHelpers/TestRequestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@

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.Globalization;
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;
using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities;
using Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher;
using Microsoft.VisualStudio.TestPlatform.CommandLine.Resources;
using Microsoft.VisualStudio.TestPlatform.CommandLineUtilities;
using Microsoft.VisualStudio.TestPlatform.Common;
using Microsoft.VisualStudio.TestPlatform.Common.Interfaces;
Expand All @@ -34,7 +25,15 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.TestPlatformHelpers
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions;
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Microsoft.VisualStudio.TestPlatform.CommandLine.Resources;
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;

/// <summary>
/// Defines the TestRequestManger which can fire off discovery and test run requests
Expand Down Expand Up @@ -267,11 +266,19 @@ public void RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLaunc
this.LogTelemetryForLegacySettings(requestData, runsettings);
}

if (!commandLineOptions.IsDesignMode)
// get Fakes data collector settings
if (!string.Equals(Environment.GetEnvironmentVariable("VSTEST_SKIP_FAKES_CONFIGURATION"), "1"))
{
// Generate fakes settings only for command line scenarios. In case of
// Editors/IDEs, this responsibility is with the caller.
GenerateFakesUtilities.GenerateFakesSettings(this.commandLineOptions, this.commandLineOptions.Sources.ToList(), ref runsettings);
// 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);
}
else if (sources.Any())
{
GenerateFakesUtilities.GenerateFakesSettings(this.commandLineOptions, sources, ref runsettings);
}
}

if (testRunRequestPayload.Sources != null && testRunRequestPayload.Sources.Any())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@
namespace TestPlatform.Common.UnitTests.Utilities
{
using System;
using System.IO;
using System.Xml;
using Microsoft.VisualStudio.TestPlatform.Common.Utilities;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class FakesUtilitiesTests
{

[TestMethod]
public void FakesSettingsShouldBeNotGeneratedIfTargetFrameWorkIsNetCore()
{
string runSettingsXml = @"<RunSettings><RunConfiguration><TargetFrameworkVersion>.netstandard,Version=5.0</TargetFrameworkVersion></RunConfiguration ></RunSettings>";
var generatedRunSettings = FakesUtilities.GenerateFakesSettingsForRunConfiguration(new string[] { }, runSettingsXml);
Assert.AreEqual(generatedRunSettings, runSettingsXml);
}

[TestMethod]
public void FakesSettingsShouldThrowExceptionIfSourcesArePassedAsNull()
{
Expand All @@ -35,9 +30,95 @@ public void FakesSettingsShouldThrowExceptionIfRunSettingsIsPassedAsNull()
[TestMethod]
public void FakesSettingsShouldBeNotGeneratedIfFakeConfiguratorAssemblyIsNotPresent()
{
string runSettingsXml = @"<RunSettings><RunConfiguration></RunConfiguration ></RunSettings>";
string runSettingsXml = @"<RunSettings><RunConfiguration></RunConfiguration></RunSettings>";
var generatedRunSettings = FakesUtilities.GenerateFakesSettingsForRunConfiguration(new string[] {@"C:\temp\UT.dll" }, runSettingsXml);
Assert.AreEqual(generatedRunSettings, runSettingsXml);
}

[TestMethod]
public void FakesDataCollectorSettingsShouldBeOverridden()
{
string runSettingsXml = @"<RunSettings><RunConfiguration></RunConfiguration></RunSettings>";
var doc = new XmlDocument();
using (var xmlReader = XmlReader.Create(
new StringReader(runSettingsXml),
new XmlReaderSettings() { CloseInput = true }))
{
doc.Load(xmlReader);
}

var dataCollectorNode = new DataCollectorSettings()
{
AssemblyQualifiedName = FakesUtilities.FakesMetadata.DataCollectorAssemblyQualifiedName,
Uri = new Uri(FakesUtilities.FakesMetadata.DataCollectorUriV1),
FriendlyName = FakesUtilities.FakesMetadata.FriendlyName,
IsEnabled = true,
Configuration = doc.FirstChild as XmlElement
};
XmlRunSettingsUtilities.InsertDataCollectorsNode(doc.CreateNavigator(), dataCollectorNode);

var dataCollectorNode2 = new DataCollectorSettings()
{
AssemblyQualifiedName = FakesUtilities.FakesMetadata.DataCollectorAssemblyQualifiedName,
Uri = new Uri(FakesUtilities.FakesMetadata.DataCollectorUriV2),
FriendlyName = FakesUtilities.FakesMetadata.FriendlyName,
IsEnabled = true,
Configuration = doc.FirstChild as XmlElement
};
FakesUtilities.InsertOrReplaceFakesDataCollectorNode(doc, dataCollectorNode2);

Assert.IsFalse(XmlRunSettingsUtilities.ContainsDataCollector(doc, FakesUtilities.FakesMetadata.DataCollectorUriV1));
Assert.IsTrue(XmlRunSettingsUtilities.ContainsDataCollector(doc, FakesUtilities.FakesMetadata.DataCollectorUriV2));
}

[TestMethod]
public void FakesDataCollectorSettingsShouldBeInserted()
{
string runSettingsXml = @"<RunSettings><RunConfiguration></RunConfiguration></RunSettings>";
var doc = new XmlDocument();
using (var xmlReader = XmlReader.Create(
new StringReader(runSettingsXml),
new XmlReaderSettings() { CloseInput = true }))
{
doc.Load(xmlReader);
}

var dataCollectorNode2 = new DataCollectorSettings()
{
AssemblyQualifiedName = FakesUtilities.FakesMetadata.DataCollectorAssemblyQualifiedName,
Uri = new Uri(FakesUtilities.FakesMetadata.DataCollectorUriV2),
FriendlyName = FakesUtilities.FakesMetadata.FriendlyName,
IsEnabled = true,
Configuration = doc.FirstChild as XmlElement
};
FakesUtilities.InsertOrReplaceFakesDataCollectorNode(doc, dataCollectorNode2);
Assert.IsTrue(XmlRunSettingsUtilities.ContainsDataCollector(doc, FakesUtilities.FakesMetadata.DataCollectorUriV2));
}

[TestMethod]
public void OtherRunsettingsShouldNotBeChanged()
{
string runSettingsXml = @"<RunSettings><RunConfiguration><TargetFrameworkVersion>FrameworkCore10</TargetFrameworkVersion></RunConfiguration></RunSettings>";
var doc = new XmlDocument();
using (var xmlReader = XmlReader.Create(
new StringReader(runSettingsXml),
new XmlReaderSettings() { CloseInput = true }))
{
doc.Load(xmlReader);
}

var dataCollectorNode2 = new DataCollectorSettings()
{
AssemblyQualifiedName = FakesUtilities.FakesMetadata.DataCollectorAssemblyQualifiedName,
Uri = new Uri(FakesUtilities.FakesMetadata.DataCollectorUriV2),
FriendlyName = FakesUtilities.FakesMetadata.FriendlyName,
IsEnabled = true,
Configuration = doc.CreateElement("Configuration")
};
FakesUtilities.InsertOrReplaceFakesDataCollectorNode(doc, dataCollectorNode2);
vritant24 marked this conversation as resolved.
Show resolved Hide resolved
Assert.IsTrue(XmlRunSettingsUtilities.ContainsDataCollector(doc, FakesUtilities.FakesMetadata.DataCollectorUriV2));
XmlNodeList nodes = doc.SelectNodes("//RunSettings/RunConfiguration/TargetFrameworkVersion");
Assert.AreEqual(nodes[0].InnerText, "FrameworkCore10");
}
}
}