diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRun.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRun.cs index 94e9449af8..00aad9b8e5 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRun.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRun.cs @@ -191,7 +191,7 @@ private static string FormatDateTimeForRunName(DateTime timeStamp) { // We use custom format string to make sure that runs are sorted in the same way on all intl machines. // This is both for directory names and for Data Warehouse. - return timeStamp.ToString("yyyy-MM-dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo); + return timeStamp.ToString("yyyy-MM-dd HH:mm:ss:fff", DateTimeFormatInfo.InvariantInfo); } private void Initialize() diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs index fe26288e64..2f7c6d8841 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs @@ -441,17 +441,13 @@ private void HandleSkippedTest(ObjectModel.TestResult rsTestResult) private void DeriveTrxFilePath() { - if (this.parametersDictionary != null) + if (this.parametersDictionary != null && + this.parametersDictionary.TryGetValue(TrxLoggerConstants.LogFileNameKey, out string logFileNameValue) && + !string.IsNullOrWhiteSpace(logFileNameValue)) { - var isLogFileNameParameterExists = this.parametersDictionary.TryGetValue(TrxLoggerConstants.LogFileNameKey, out string logFileNameValue); - if (isLogFileNameParameterExists && !string.IsNullOrWhiteSpace(logFileNameValue)) - { - this.trxFilePath = Path.Combine(this.testResultsDirPath, logFileNameValue); - } - else - { - this.SetDefaultTrxFilePath(); - } + string logFileNameWithoutExt = Path.GetFileNameWithoutExtension(logFileNameValue); + logFileNameValue = logFileNameValue.Replace(logFileNameWithoutExt, logFileNameWithoutExt + DateTime.Now.ToString("_yyyy-MM-dd_HH-mm-ss-fff", DateTimeFormatInfo.InvariantInfo)); + this.trxFilePath = Path.Combine(this.testResultsDirPath, logFileNameValue); } else { diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/CodeCoverageTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/CodeCoverageTests.cs index d57fa665a6..4da1842c88 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/CodeCoverageTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/CodeCoverageTests.cs @@ -59,14 +59,27 @@ private void CollectCodeCoverage(RunnerInfo runnerInfo, string targetPlatform, b { AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); - var arguments = CreateArguments(runnerInfo, targetPlatform, withRunsettings, out var trxFilePath); + var trxFileName = Guid.NewGuid().ToString(); + var trxFileNamePattern = trxFileName + "*.trx"; + var arguments = CreateArguments(runnerInfo, targetPlatform, withRunsettings, trxFileName); + // Delete existing trx files + var dir = new DirectoryInfo(this.resultsDirectory); + if (dir.Exists) + { + foreach (var file in dir.EnumerateFiles(trxFileNamePattern)) + { + file.Delete(); + } + } + + // Invoke tests this.InvokeVsTest(arguments); + // Validate this.ValidateSummaryStatus(1, 1, 1); - - var actualCoverageFile = CodeCoverageTests.GetCoverageFileNameFromTrx(trxFilePath, resultsDirectory); - Console.WriteLine($@"Coverage file: {actualCoverageFile} Results directory: {resultsDirectory} trxfile: {trxFilePath}"); + var actualCoverageFile = CodeCoverageTests.GetCoverageFileNameFromTrx(trxFileNamePattern, this.resultsDirectory); + Console.WriteLine($@"Coverage file: {actualCoverageFile} Results directory: {resultsDirectory} trxfile pattern: {trxFileNamePattern}"); Assert.IsTrue(File.Exists(actualCoverageFile), "Coverage file not found: {0}", actualCoverageFile); // Microsoft.VisualStudio.Coverage.Analysis assembly not avaialble for .NET Core. @@ -76,8 +89,7 @@ private void CollectCodeCoverage(RunnerInfo runnerInfo, string targetPlatform, b Directory.Delete(this.resultsDirectory, true); } - private string CreateArguments(RunnerInfo runnerInfo, string targetPlatform, bool withRunsettings, - out string trxFilePath) + private string CreateArguments(RunnerInfo runnerInfo, string targetPlatform, bool withRunsettings, string trxFileName) { var assemblyPaths = this.GetAssetFullPath(assemblyName); string runSettings = Path.Combine(IntegrationTestEnvironment.TestPlatformRootDirectory, @@ -93,7 +105,7 @@ private string CreateArguments(RunnerInfo runnerInfo, string targetPlatform, boo $" /TestAdapterPath:{traceDataCollectorDir}"); arguments = string.Concat(arguments, $" /Platform:{targetPlatform}"); - trxFilePath = Path.Combine(this.resultsDirectory, Guid.NewGuid() + ".trx"); + var trxFilePath = Path.Combine(this.resultsDirectory, trxFileName + ".trx"); arguments = string.Concat(arguments, " /logger:trx;logfilename=" + trxFilePath); if (withRunsettings) @@ -148,9 +160,11 @@ private void AssertModuleCoverageCollected(CoverageDS coverageDS) } #endif - private static string GetCoverageFileNameFromTrx(string trxFilePath, string resultsDirectory) + private static string GetCoverageFileNameFromTrx(string trxFileNamePattern, string resultsDirectory) { - Assert.IsTrue(File.Exists(trxFilePath), "Trx file not found: {0}", trxFilePath); + var trxFiles = Directory.EnumerateFiles(resultsDirectory, trxFileNamePattern); + Assert.IsTrue(trxFiles.Any(), "Trx file with pattern: {0} not found", trxFileNamePattern); + var trxFilePath = trxFiles.First(); XmlDocument doc = new XmlDocument(); using (var trxStream = new FileStream(trxFilePath, FileMode.Open, FileAccess.Read)) { diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/LoggerTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/LoggerTests.cs index 7eb8b5e08b..88b36b44b6 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/LoggerTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/LoggerTests.cs @@ -8,6 +8,7 @@ namespace Microsoft.TestPlatform.AcceptanceTests { using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Linq; [TestClass] public class LoggerTests : AcceptanceTestBase @@ -20,6 +21,7 @@ public void TrxLoggerWithFriendlyNameShouldProperlyOverwriteFile(RunnerInfo runn var arguments = PrepareArguments(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty, this.FrameworkArgValue, runnerInfo.InIsolationValue); var trxFileName = "TestResults.trx"; + var trxFileNamePattern = "TestResults*.trx"; arguments = string.Concat(arguments, $" /logger:\"trx;LogFileName={trxFileName}\""); this.InvokeVsTest(arguments); @@ -28,7 +30,7 @@ public void TrxLoggerWithFriendlyNameShouldProperlyOverwriteFile(RunnerInfo runn arguments = string.Concat(arguments, " /testcasefilter:Name~Pass"); this.InvokeVsTest(arguments); - var trxLogFilePath = Path.Combine(Directory.GetCurrentDirectory(), "TestResults", trxFileName); + var trxLogFilePath = Directory.EnumerateFiles(Path.Combine(Directory.GetCurrentDirectory(), "TestResults"), trxFileNamePattern).First(); Assert.IsTrue(IsValidXml(trxLogFilePath), "Invalid content in Trx log file"); } @@ -40,6 +42,7 @@ public void TrxLoggerWithExecutorUriShouldProperlyOverwriteFile(RunnerInfo runne var arguments = PrepareArguments(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty, this.FrameworkArgValue, runnerInfo.InIsolationValue); var trxFileName = "TestResults.trx"; + var trxFileNamePattern = "TestResults*.trx"; arguments = string.Concat(arguments, $" /logger:\"logger://Microsoft/TestPlatform/TrxLogger/v1;LogFileName{trxFileName}\""); this.InvokeVsTest(arguments); @@ -48,7 +51,7 @@ public void TrxLoggerWithExecutorUriShouldProperlyOverwriteFile(RunnerInfo runne arguments = string.Concat(arguments, " /testcasefilter:Name~Pass"); this.InvokeVsTest(arguments); - var trxLogFilePath = Path.Combine(Directory.GetCurrentDirectory(), "TestResults", trxFileName); + var trxLogFilePath = Directory.EnumerateFiles(Path.Combine(Directory.GetCurrentDirectory(), "TestResults"), trxFileNamePattern).First(); Assert.IsTrue(IsValidXml(trxLogFilePath), "Invalid content in Trx log file"); } diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/ResultsDirectoryTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/ResultsDirectoryTests.cs index 0f73ba33af..262794a8c6 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/ResultsDirectoryTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/ResultsDirectoryTests.cs @@ -4,6 +4,7 @@ namespace Microsoft.TestPlatform.AcceptanceTests { using System.IO; + using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -16,18 +17,22 @@ public void TrxFileShouldBeCreatedInResultsDirectory(RunnerInfo runnerInfo) { AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); var arguments = PrepareArguments(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty, this.FrameworkArgValue, runnerInfo.InIsolationValue); - var trxFileName = "TestResults.trx"; + var trxFileName = "TestResultsbla.trx"; + var trxFileNamePattern = "TestResultsbla*.trx"; var resultsDir = Path.GetTempPath(); - var trxFilePath = Path.Combine(resultsDir, trxFileName); arguments = string.Concat(arguments, $" /logger:\"trx;LogFileName={trxFileName}\""); arguments = string.Concat(arguments, $" /ResultsDirectory:{resultsDir}"); // Delete if already exists - File.Delete(trxFilePath); + var dir = new DirectoryInfo(resultsDir); + foreach (var file in dir.EnumerateFiles(trxFileNamePattern)) + { + file.Delete(); + } this.InvokeVsTest(arguments); - Assert.IsTrue(File.Exists(trxFilePath), $"Expected Trx file: {trxFilePath} not created in results directory"); + Assert.IsTrue(Directory.EnumerateFiles(resultsDir, trxFileNamePattern).Any(), $"Expected Trx file with pattern: {trxFileNamePattern} not created in results directory"); } [TestMethod] @@ -39,10 +44,10 @@ public void ResultsDirectoryRelativePathShouldWork(RunnerInfo runnerInfo) var arguments = PrepareArguments(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty, this.FrameworkArgValue, runnerInfo.InIsolationValue); var trxFileName = "TestResults.trx"; + var trxFileNamePattern = "TestResults*.trx"; var relativeDirectory = @"relative\directory"; var resultsDirectory = Path.Combine(Directory.GetCurrentDirectory(), relativeDirectory); - var trxFilePath = Path.Combine(resultsDirectory , trxFileName); arguments = string.Concat(arguments, $" /logger:\"trx;LogFileName={trxFileName}\""); arguments = string.Concat(arguments, $" /ResultsDirectory:{relativeDirectory}"); @@ -53,7 +58,7 @@ public void ResultsDirectoryRelativePathShouldWork(RunnerInfo runnerInfo) this.InvokeVsTest(arguments); - Assert.IsTrue(File.Exists(trxFilePath), $"Expected Trx file: {trxFilePath} not created in results directory"); + Assert.IsTrue(Directory.EnumerateFiles(resultsDirectory, trxFileNamePattern).Any(), $"Expected Trx file with pattern: { trxFileNamePattern} not created in results directory"); } } } diff --git a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs index 51e16e0e5b..0f66b40a56 100644 --- a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs @@ -637,7 +637,12 @@ public void CustomTrxFileNameShouldConstructFromLogFileParameter() { this.MakeTestRunComplete(); - Assert.AreEqual(Path.Combine(TrxLoggerTests.DefaultTestRunDirectory, TrxLoggerTests.DefaultLogFileNameParameterValue), this.testableTrxLogger.trxFile, "Wrong Trx file name"); + string expectedFileNameWithoutTimestamp = Path.Combine(TrxLoggerTests.DefaultTestRunDirectory, TrxLoggerTests.DefaultLogFileNameParameterValue); + string fileName = Path.GetFileNameWithoutExtension(this.testableTrxLogger.trxFile); + string actualFileNameWithoutTimestamp = this.testableTrxLogger.trxFile.Replace(fileName, fileName.Split('_')[0]); + + Assert.AreNotEqual(expectedFileNameWithoutTimestamp, this.testableTrxLogger.trxFile, "Expected time stamp to appear in file name"); + Assert.AreEqual(expectedFileNameWithoutTimestamp, actualFileNameWithoutTimestamp, "Trx file name should construct from log file parameter"); } ///