From fd2a38dfe3ea3d349b44feaf6f49cbe9afe1c8f8 Mon Sep 17 00:00:00 2001
From: Marco Rossignoli <marco.rossignoli@gmail.com>
Date: Wed, 16 Feb 2022 16:17:46 +0100
Subject: [PATCH] add post processing intergration test (#3377)

---
 .../PostProcessingTests.cs                    | 122 ++++++++++++++++++
 .../IntegrationTestBase.cs                    |   4 +-
 .../SampleDataCollector.cs                    |   2 +-
 3 files changed, 125 insertions(+), 3 deletions(-)
 create mode 100644 test/Microsoft.TestPlatform.AcceptanceTests/PostProcessingTests.cs

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<string, string>() { { "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<string, string>() { { "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<string>();
+        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<string, string>
+        {
+            { "friendlyName", "SampleDataCollector" },
+            { "uri", "my://sample/datacollector" }
+        };
+
+        CreateDataCollectionRunSettingsFile(runsettingsPath, dataCollectionAttributes);
+        return runsettingsPath;
+    }
+
+    private static void CreateDataCollectionRunSettingsFile(string destinationRunsettingsPath, Dictionary<string, string> 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<string, string> environmentVariables = null)
+    protected void ExecuteVsTestConsole(string args, out string stdOut, out string stdError, out int exitCode, Dictionary<string, string> 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<string, string> environmentVariables = null, string workingDirectory = null)
+    protected static void ExecuteApplication(string path, string args, out string stdOut, out string stdError, out int exitCode, Dictionary<string, string> 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<ICollection<AttachmentSet>> ProcessAttachmentSetsAsync(XmlElement co
                         finalFolder = Path.GetDirectoryName(attachment.Uri.AbsolutePath);
                     }
 
-                    stringBuilder.AppendLine(File.ReadAllText(attachment.Uri.AbsolutePath));
+                    stringBuilder.AppendLine(File.ReadAllText(attachment.Uri.AbsolutePath).Trim());
                 }
             }