diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/PostProcessingTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/PostProcessingTests.cs new file mode 100644 index 0000000000..35272db0eb --- /dev/null +++ b/test/Microsoft.TestPlatform.AcceptanceTests/PostProcessingTests.cs @@ -0,0 +1,122 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.TestPlatform.AcceptanceTests; + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; + +using Microsoft.TestPlatform.TestUtilities; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class PostProcessingTests : AcceptanceTestBase +{ + [TestMethod] + public void DotnetSDKSimulation_PostProcessing() + { + using var tempDir = new TempDirectory(); + + var extensionsPath = Path.Combine( + _testEnvironment.TestAssetsPath, + Path.GetFileNameWithoutExtension("AttachmentProcessorDataCollector"), + "bin", + IntegrationTestEnvironment.BuildConfiguration, + "netstandard2.0"); + _testEnvironment.RunnerFramework = CoreRunnerFramework; + + string runSettings = GetRunsettingsFilePath(tempDir.Path); + string correlationSessionId = Guid.NewGuid().ToString(); + + // Set datacollector parameters + XElement runSettingsXml = XElement.Load(runSettings); + runSettingsXml.Element("DataCollectionRunSettings") + .Element("DataCollectors") + .Element("DataCollector") + .Add(new XElement("Configuration", new XElement("MergeFile", "MergedFile.txt"))); + runSettingsXml.Save(runSettings); + + // Build and run tests like msbuild + Parallel.For(0, 5, i => + { + string projectFolder = Path.Combine(tempDir.Path, i.ToString()); + ExecuteApplication(GetConsoleRunnerPath(), $"new mstest -o {projectFolder}", out string stdOut, out string stdError, out int exitCode); + Assert.AreEqual(exitCode, 0); + ExecuteApplication(GetConsoleRunnerPath(), $"build {projectFolder} -c release", out stdOut, out stdError, out exitCode); + Assert.AreEqual(exitCode, 0); + + string testContainer = Directory.GetFiles(Path.Combine(projectFolder, "bin"), $"{i}.dll", SearchOption.AllDirectories).Single(); + + ExecuteVsTestConsole($"{testContainer} --Collect:\"SampleDataCollector\" --TestAdapterPath:\"{extensionsPath}\" --ResultsDirectory:\"{Path.GetDirectoryName(testContainer)}\" --Settings:\"{runSettings}\" --ArtifactsProcessingMode-Collect --TestSessionCorrelationId:\"{correlationSessionId}\" --Diag:\"{tempDir.Path + '/'}\"", out stdOut, out stdError, out exitCode, + new Dictionary() { { "VSTEST_FEATURE_ARTIFACTS_POSTPROCESSING", "1" } }); + Assert.AreEqual(exitCode, 0); + }); + + // Post process artifacts + ExecuteVsTestConsole($"--ArtifactsProcessingMode-PostProcess --TestSessionCorrelationId:\"{correlationSessionId}\" --Diag:\"{tempDir.Path + '/'}\"", out string stdOut, out string stdError, out int exitCode, + new Dictionary() { { "VSTEST_FEATURE_ARTIFACTS_POSTPROCESSING", "1" } }); + Assert.AreEqual(exitCode, 0); + + using StringReader reader = new(stdOut); + Assert.AreEqual(string.Empty, reader.ReadLine().Trim()); + Assert.AreEqual("Attachments:", reader.ReadLine().Trim()); + string mergedFile = reader.ReadLine().Trim(); + Assert.AreEqual(string.Empty, reader.ReadLine().Trim()); + Assert.IsNull(reader.ReadLine()); + + var fileContent = new List(); + using var streamReader = new StreamReader(mergedFile); + while (!streamReader.EndOfStream) + { + string line = streamReader.ReadLine(); + Assert.IsTrue(line.StartsWith("SessionEnded_Handler_")); + fileContent.Add(line); + } + + Assert.AreEqual(5, fileContent.Distinct().Count()); + } + + private static string GetRunsettingsFilePath(string resultsDir) + { + var runsettingsPath = Path.Combine(resultsDir, "test_" + Guid.NewGuid() + ".runsettings"); + var dataCollectionAttributes = new Dictionary + { + { "friendlyName", "SampleDataCollector" }, + { "uri", "my://sample/datacollector" } + }; + + CreateDataCollectionRunSettingsFile(runsettingsPath, dataCollectionAttributes); + return runsettingsPath; + } + + private static void CreateDataCollectionRunSettingsFile(string destinationRunsettingsPath, Dictionary dataCollectionAttributes) + { + var doc = new XmlDocument(); + var xmlDeclaration = doc.CreateNode(XmlNodeType.XmlDeclaration, string.Empty, string.Empty); + + doc.AppendChild(xmlDeclaration); + var runSettingsNode = doc.CreateElement(Constants.RunSettingsName); + doc.AppendChild(runSettingsNode); + var dcConfigNode = doc.CreateElement(Constants.DataCollectionRunSettingsName); + runSettingsNode.AppendChild(dcConfigNode); + var dataCollectorsNode = doc.CreateElement(Constants.DataCollectorsSettingName); + dcConfigNode.AppendChild(dataCollectorsNode); + var dataCollectorNode = doc.CreateElement(Constants.DataCollectorSettingName); + dataCollectorsNode.AppendChild(dataCollectorNode); + + foreach (var kvp in dataCollectionAttributes) + { + dataCollectorNode.SetAttribute(kvp.Key, kvp.Value); + } + + using var stream = new FileHelper().GetStream(destinationRunsettingsPath, FileMode.Create); + doc.Save(stream); + } +} diff --git a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs index 381aab143a..cf0ee5b0de 100644 --- a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs +++ b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs @@ -559,7 +559,7 @@ private static string GetTestMethodName(string testFullName) return testMethodName; } - private void ExecuteVsTestConsole(string args, out string stdOut, out string stdError, out int exitCode, Dictionary environmentVariables = null) + protected void ExecuteVsTestConsole(string args, out string stdOut, out string stdError, out int exitCode, Dictionary environmentVariables = null) { if (IsNetCoreRunner()) { @@ -592,7 +592,7 @@ private void ExecutePatchedDotnet(string command, string args, out string stdOut ExecuteApplication(patchedDotnetPath, string.Join(" ", command, args), out stdOut, out stdError, out exitCode, environmentVariables); } - protected void ExecuteApplication(string path, string args, out string stdOut, out string stdError, out int exitCode, Dictionary environmentVariables = null, string workingDirectory = null) + protected static void ExecuteApplication(string path, string args, out string stdOut, out string stdError, out int exitCode, Dictionary environmentVariables = null, string workingDirectory = null) { if (string.IsNullOrWhiteSpace(path)) { diff --git a/test/TestAssets/AttachmentProcessorDataCollector/SampleDataCollector.cs b/test/TestAssets/AttachmentProcessorDataCollector/SampleDataCollector.cs index d6a42b9d15..a686286095 100644 --- a/test/TestAssets/AttachmentProcessorDataCollector/SampleDataCollector.cs +++ b/test/TestAssets/AttachmentProcessorDataCollector/SampleDataCollector.cs @@ -78,7 +78,7 @@ public Task> ProcessAttachmentSetsAsync(XmlElement co finalFolder = Path.GetDirectoryName(attachment.Uri.AbsolutePath); } - stringBuilder.AppendLine(File.ReadAllText(attachment.Uri.AbsolutePath)); + stringBuilder.AppendLine(File.ReadAllText(attachment.Uri.AbsolutePath).Trim()); } }