diff --git a/src/Microsoft.TestPlatform.Build/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.Build/Resources/xlf/Resources.tr.xlf index 97d16a5591..61f26907e5 100644 --- a/src/Microsoft.TestPlatform.Build/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.Build/Resources/xlf/Resources.tr.xlf @@ -47,4 +47,4 @@ - + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResult.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResult.cs index 661d7fc9fb..ea6e327b2c 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResult.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResult.cs @@ -231,6 +231,7 @@ internal class TestResult : ITestResult, IXmlTestStore /// Directory containing the test result files, relative to the root test results directory /// private string relativeTestResultsDirectory; + private readonly TrxFileHelper trxFileHelper; /// /// Paths to test result files, relative to the test results folder, sorted in increasing order @@ -270,7 +271,8 @@ public TestResult( string computerName, TestOutcome outcome, TestType testType, - TestListCategoryId testCategoryId) + TestListCategoryId testCategoryId, + TrxFileHelper trxFileHelper) { Debug.Assert(computerName != null, "computername is null"); Debug.Assert(!Guid.Empty.Equals(executionId), "ExecutionId is empty"); @@ -285,6 +287,7 @@ public TestResult( this.outcome = outcome; this.categoryId = testCategoryId; this.relativeTestResultsDirectory = TestRunDirectories.GetRelativeTestResultsDirectory(executionId); + this.trxFileHelper = trxFileHelper; } #endregion @@ -532,7 +535,7 @@ internal void AddResultFiles(IEnumerable resultFileList) Debug.Assert(!string.IsNullOrEmpty(resultFile), "'resultFile' is null or empty"); Debug.Assert(resultFile.Trim() == resultFile, "'resultFile' has whitespace at the ends"); - this.resultFiles[FileHelper.MakePathRelative(resultFile, testResultsDirectory)] = null; + this.resultFiles[trxFileHelper.MakePathRelative(resultFile, testResultsDirectory)] = null; } } diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResultAggregation.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResultAggregation.cs index 1561fa287e..8c06d8ec58 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResultAggregation.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResultAggregation.cs @@ -5,6 +5,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel { using System; using System.Collections.Generic; + using Microsoft.TestPlatform.Extensions.TrxLogger.Utility; using Microsoft.TestPlatform.Extensions.TrxLogger.XML; /// @@ -23,7 +24,8 @@ public TestResultAggregation( string computerName, TestOutcome outcome, TestType testType, - TestListCategoryId testCategoryId) : base(runId, testId, executionId, parentExecutionId, resultName, computerName, outcome, testType, testCategoryId) { } + TestListCategoryId testCategoryId, + TrxFileHelper trxFileHelper) : base(runId, testId, executionId, parentExecutionId, resultName, computerName, outcome, testType, testCategoryId, trxFileHelper) { } /// /// Gets the inner results. diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRunConfiguration.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRunConfiguration.cs index e4b99888c1..4d4d6ab430 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRunConfiguration.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRunConfiguration.cs @@ -20,6 +20,7 @@ internal class TestRunConfiguration : IXmlTestStore, IXmlTestStoreCustom #region Fields private TestRunConfigurationId id; + private readonly TrxFileHelper trxFileHelper; [StoreXmlSimpleField(DefaultValue = "")] private string name; @@ -34,14 +35,17 @@ internal class TestRunConfiguration : IXmlTestStore, IXmlTestStoreCustom /// /// The name of Run Configuration. /// - public TestRunConfiguration(string name) + /// + /// InternalFileHelper instance to use in file operations. + /// + internal TestRunConfiguration(string name, TrxFileHelper trxFileHelper) { EqtAssert.ParameterNotNull(name, "name"); this.name = name; - this.runDeploymentRoot = string.Empty; this.id = new TestRunConfigurationId(); + this.trxFileHelper = trxFileHelper; } #region IXmlTestStoreCustom Members @@ -141,7 +145,7 @@ public void Save(XmlElement element, XmlTestStoreParameters parameters) helper.SaveSimpleField( element, "Deployment/@runDeploymentRoot", - FileHelper.MakePathRelative(this.runDeploymentRoot, Path.GetDirectoryName(this.runDeploymentRoot)), + trxFileHelper.MakePathRelative(this.runDeploymentRoot, Path.GetDirectoryName(this.runDeploymentRoot)), string.Empty); } else diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestResult.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestResult.cs index 66c815765e..d37352497c 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestResult.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestResult.cs @@ -4,6 +4,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel { using System; + using Microsoft.TestPlatform.Extensions.TrxLogger.Utility; /// /// Class for unit test result. @@ -19,6 +20,8 @@ public UnitTestResult( string computerName, TestOutcome outcome, TestType testType, - TestListCategoryId testCategoryId) : base(runId, testId, executionId, parentExecutionId, resultName, computerName, outcome, testType, testCategoryId) { } + TestListCategoryId testCategoryId, + TrxFileHelper trxFileHelper + ) : base(runId, testId, executionId, parentExecutionId, resultName, computerName, outcome, testType, testCategoryId, trxFileHelper) { } } } diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UriDataAttachment.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UriDataAttachment.cs index e61184b7c7..ee5d05bb29 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UriDataAttachment.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UriDataAttachment.cs @@ -17,6 +17,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel /// internal class UriDataAttachment : IDataAttachment, IXmlTestStore { + private readonly TrxFileHelper trxFileHelper; #region Private fields /// @@ -36,11 +37,14 @@ internal class UriDataAttachment : IDataAttachment, IXmlTestStore /// /// Short description for the attachment /// The URI pointing to the resource + /// InternalFileHelper class instance to use in file operations. /// 'name' is null or empty /// 'uri' is null - public UriDataAttachment(string description, Uri uri) + public UriDataAttachment(string description, Uri uri, TrxFileHelper trxFileHelper) { - this.Initialize(description, uri); + this.trxFileHelper = trxFileHelper; + + Initialize(description, uri); } #region IDataAttachment Members @@ -121,10 +125,10 @@ internal UriDataAttachment Clone(string baseDirectory, bool useAbsoluteUri) } else { - uriToUse = new Uri(FileHelper.MakePathRelative(this.uri.OriginalString, baseDirectory), UriKind.Relative); + uriToUse = new Uri(trxFileHelper.MakePathRelative(this.uri.OriginalString, baseDirectory), UriKind.Relative); } - return new UriDataAttachment(this.description, uriToUse); + return new UriDataAttachment(this.description, uriToUse, trxFileHelper); } // The URI in this instance is already how we want it, and since this class is immutable, no need to clone diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/TrxResource.Designer.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/TrxResource.Designer.cs index 2bb4a683ae..21303cc06e 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/TrxResource.Designer.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/TrxResource.Designer.cs @@ -87,6 +87,15 @@ internal static string Common_CannotGetNextIterationName { } } + /// + /// Looks up a localized string similar to Cannot get find an available filename for {0} using timestamp format '{2}' at {1}.. + /// + internal static string Common_CannotGetNextTimestampFileName { + get { + return ResourceManager.GetString("Common_CannotGetNextTimestampFileName", resourceCulture); + } + } + /// /// Looks up a localized string similar to deployment item '{0}'. /// diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/TrxResource.resx b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/TrxResource.resx index b50850a64f..b7bd4433b2 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/TrxResource.resx +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/TrxResource.resx @@ -214,4 +214,7 @@ Error Details: {1}:{2} The parameters LogFileName and LogFilePrefix cannot be used together. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.cs.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.cs.xlf index c11126e9c5..47705beeaa 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.cs.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.cs.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} Parametry LogFileName a LogFilePrefix nejde použít společně. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.de.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.de.xlf index d85ea85ca8..a3ff187953 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.de.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.de.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} Die Parameter "LogFileName" und "LogFilePrefix" können nicht zusammen verwendet werden. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.es.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.es.xlf index 8866a8786f..bd533f167c 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.es.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.es.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} Los parámetros LogFileName y LogFilePrefix no se pueden usar juntos. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.fr.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.fr.xlf index 7dbdabd118..76c95a72d4 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.fr.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.fr.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} Les paramètres LogFileName et LogFilePrefix ne peuvent pas être utilisés ensemble. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.it.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.it.xlf index bd04a954b3..754df4bd28 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.it.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.it.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} Non è possibile usare insieme i parametri LogFileName e LogFilePrefix. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ja.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ja.xlf index f909a48a99..28c923da3a 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ja.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ja.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} パラメーター LogFileName と LogFilePrefix を同時に使用することはできません。 + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ko.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ko.xlf index 01656272f0..ef3f078165 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ko.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ko.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} LogFileName 및 LogFilePrefix 매개 변수는 함께 사용할 수 없습니다. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.pl.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.pl.xlf index c511ef3305..bdbedc31ad 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.pl.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.pl.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} Parametry LogFileName i LogFilePrefix nie mogą być używane razem. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.pt-BR.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.pt-BR.xlf index 2820671aa9..dd2c12574f 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.pt-BR.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} Os parâmetros LogFileName e LogFilePrefix não podem ser usados juntos. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ru.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ru.xlf index 819299bc6c..eafbe35699 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ru.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.ru.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} Параметры LogFileName и LogFilePrefix недопустимо использовать вместе. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.tr.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.tr.xlf index e545bbc9e5..21c1b93cd0 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.tr.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.tr.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} LogFileName ve LogFilePrefix parametreleri birlikte kullanılamaz. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + "{1}" altında "{2}" biçimlendirmesi ve "{0}" ismi kullanılarak müsait bir dosya adı bulunamadı. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.xlf index 31f1cbdf24..7268b9dbc7 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.xlf @@ -133,6 +133,11 @@ Error Details: {1}:{2} The parameters LogFileName and LogFilePrefix cannot be given together. + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.zh-Hans.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.zh-Hans.xlf index 1dcb92dbf6..4d87c2e95f 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.zh-Hans.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} 参数 LogFileName 和 LogFilePrefix 不能一起使用。 + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.zh-Hant.xlf b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.zh-Hant.xlf index db7b564bb6..079adba278 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Resources/xlf/TrxResource.zh-Hant.xlf @@ -303,6 +303,11 @@ Fehlerdetails: {1}: {2} 不能同時使用參數 LogFileName 和 LogFilePrefix。 + + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + Cannot get find an available filename for {0} using timestamp format '{2}' at {1}. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs index 6819883599..0c669ecfc8 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs @@ -3,6 +3,15 @@ namespace Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger { + using Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel; + using Microsoft.TestPlatform.Extensions.TrxLogger.Utility; + using Microsoft.TestPlatform.Extensions.TrxLogger.XML; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.Utilities; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; + using NuGet.Frameworks; + using ObjectModel.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -11,17 +20,8 @@ namespace Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger using System.Globalization; using System.IO; using System.Text; + using System.Threading; using System.Xml; - using Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel; - using Microsoft.TestPlatform.Extensions.TrxLogger.Utility; - using Microsoft.TestPlatform.Extensions.TrxLogger.XML; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; - using Microsoft.VisualStudio.TestPlatform.Utilities; - using NuGet.Frameworks; - using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; - using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; - using ObjectModel.Logging; using TrxLoggerConstants = Microsoft.TestPlatform.Extensions.TrxLogger.Utility.Constants; using TrxLoggerObjectModel = Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel; using TrxLoggerResources = Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.Resources.TrxResource; @@ -33,30 +33,30 @@ namespace Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger [ExtensionUri(TrxLoggerConstants.ExtensionUri)] public class TrxLogger : ITestLoggerWithParameters { - #region Fields - #region Constructor /// /// Initializes a new instance of the class. /// - public TrxLogger(): - this (new Utilities.Helpers.FileHelper()) - { - } + public TrxLogger() : this(new Utilities.Helpers.FileHelper()) { } /// /// Initializes a new instance of the class. /// Constructor with Dependency injection. Used for unit testing. /// /// The file helper interface. - protected TrxLogger(IFileHelper fileHelper) + protected TrxLogger(IFileHelper fileHelper) : this(new Utilities.Helpers.FileHelper(), new TrxFileHelper()) { } + + internal TrxLogger(IFileHelper fileHelper, TrxFileHelper trxFileHelper) { - this.converter = new Converter(fileHelper); + this.converter = new Converter(fileHelper, trxFileHelper); + this.trxFileHelper = trxFileHelper; } #endregion + #region Fields + /// /// Cache the TRX file path /// @@ -74,6 +74,8 @@ protected TrxLogger(IFileHelper fileHelper) private ConcurrentDictionary innerResults; private ConcurrentDictionary innerTestEntries; + private readonly TrxFileHelper trxFileHelper; + /// /// Specifies the run level "out" messages /// @@ -389,8 +391,8 @@ internal void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) helper.SaveObject(runSummary, rootElement, "ResultSummary", parameters); - //Save results to Trx file - this.DeriveTrxFilePath(); + + this.ReserveTrxFilePath(); this.PopulateTrxFile(this.trxFilePath, rootElement); } @@ -407,21 +409,7 @@ internal virtual void PopulateTrxFile(string trxFileName, XmlElement rootElement { try { - var trxFileDirPath = Path.GetDirectoryName(trxFilePath); - if (Directory.Exists(trxFileDirPath) == false) - { - Directory.CreateDirectory(trxFileDirPath); - } - - if (File.Exists(trxFilePath)) - { - var overwriteWarningMsg = string.Format(CultureInfo.CurrentCulture, - TrxLoggerResources.TrxLoggerResultsFileOverwriteWarning, trxFileName); - ConsoleOutput.Instance.Warning(false, overwriteWarningMsg); - EqtTrace.Warning(overwriteWarningMsg); - } - - using (var fs = File.Open(trxFileName, FileMode.Create)) + using (var fs = File.Open(trxFileName, FileMode.Truncate)) { using (XmlWriter writer = XmlWriter.Create(fs, new XmlWriterSettings { NewLineHandling = NewLineHandling.Entitize, Indent = true })) { @@ -446,7 +434,7 @@ private void InitializeInternal() this.results = new ConcurrentDictionary(); this.innerResults = new ConcurrentDictionary(); this.testElements = new ConcurrentDictionary(); - this.entries = new ConcurrentDictionary(); + this.entries = new ConcurrentDictionary(); this.innerTestEntries = new ConcurrentDictionary(); this.runLevelErrorsAndWarnings = new List(); this.testRun = null; @@ -480,47 +468,79 @@ private void HandleSkippedTest(ObjectModel.TestResult rsTestResult) this.AddRunLevelInformationalMessage(message); } - private void DeriveTrxFilePath() + private void ReserveTrxFilePath() { - var isLogFilePrefixParameterExists = this.parametersDictionary.TryGetValue(TrxLoggerConstants.LogFilePrefixKey, out string logFilePrefixValue); - var isLogFileNameParameterExists = this.parametersDictionary.TryGetValue(TrxLoggerConstants.LogFileNameKey, out string logFileNameValue); - - if (isLogFilePrefixParameterExists) + for (short retries = 0; retries != short.MaxValue; retries++) { - if (!string.IsNullOrWhiteSpace(logFilePrefixValue)) + var filePath = AcquireTrxFileNamePath(out var shouldOverwrite); + + if (shouldOverwrite && File.Exists(filePath)) { - var framework = this.parametersDictionary[DefaultLoggerParameterNames.TargetFramework]; - if (framework != null) + var overwriteWarningMsg = string.Format(CultureInfo.CurrentCulture, TrxLoggerResources.TrxLoggerResultsFileOverwriteWarning, filePath); + ConsoleOutput.Instance.Warning(false, overwriteWarningMsg); + EqtTrace.Warning(overwriteWarningMsg); + } + else + { + try { - framework = NuGetFramework.Parse(framework).GetShortFolderName(); - logFilePrefixValue = logFilePrefixValue + "_" + framework; + using (var fs = File.Open(filePath, FileMode.CreateNew)) { } + } + catch (IOException) + { + // File already exists, try again! + continue; } - - logFilePrefixValue = logFilePrefixValue + DateTime.Now.ToString("_yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo) + this.trxFileExtension; - this.trxFilePath = Path.Combine(this.testResultsDirPath, logFilePrefixValue); - return; } + + trxFilePath = filePath; + return; } + } - else if (isLogFileNameParameterExists) + private string AcquireTrxFileNamePath(out bool shouldOverwrite) + { + shouldOverwrite = false; + var isLogFileNameParameterExists = parametersDictionary.TryGetValue(TrxLoggerConstants.LogFileNameKey, out string logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue); + var isLogFilePrefixParameterExists = parametersDictionary.TryGetValue(TrxLoggerConstants.LogFilePrefixKey, out string logFilePrefixValue) && !string.IsNullOrWhiteSpace(logFilePrefixValue); + + string filePath = null; + if (isLogFilePrefixParameterExists) { - if (!string.IsNullOrWhiteSpace(logFileNameValue)) + if (parametersDictionary.TryGetValue(DefaultLoggerParameterNames.TargetFramework, out var framework) && framework != null) { - this.trxFilePath = Path.Combine(this.testResultsDirPath, logFileNameValue); - return; + framework = NuGetFramework.Parse(framework).GetShortFolderName(); + logFilePrefixValue = logFilePrefixValue + "_" + framework; } + + filePath = trxFileHelper.GetNextTimestampFileName(this.testResultsDirPath, logFilePrefixValue + this.trxFileExtension, "_yyyyMMddHHmmss"); + } + + else if (isLogFileNameParameterExists) + { + filePath = Path.Combine(this.testResultsDirPath, logFileNameValue); + shouldOverwrite = true; + } + + filePath = filePath ?? this.SetDefaultTrxFilePath(); + + var trxFileDirPath = Path.GetDirectoryName(filePath); + if (Directory.Exists(trxFileDirPath) == false) + { + Directory.CreateDirectory(trxFileDirPath); } - this.SetDefaultTrxFilePath(); + return filePath; } /// - /// Sets auto generated Trx file name under test results directory. + /// Returns an auto generated Trx file name under test results directory. /// - private void SetDefaultTrxFilePath() + private string SetDefaultTrxFilePath() { var defaultTrxFileName = this.testRun.RunConfiguration.RunDeploymentRootDirectory + ".trx"; - this.trxFilePath = Microsoft.TestPlatform.Extensions.TrxLogger.Utility.FileHelper.GetNextIterationFileName(this.testResultsDirPath, defaultTrxFileName, false); + + return trxFileHelper.GetNextIterationFileName(this.testResultsDirPath, defaultTrxFileName, false); } /// @@ -542,8 +562,8 @@ private void CreateTestRun() this.testRun.Started = this.testRunStartTime; // Save default test settings - string runDeploymentRoot = Microsoft.TestPlatform.Extensions.TrxLogger.Utility.FileHelper.ReplaceInvalidFileNameChars(this.testRun.Name); - TestRunConfiguration testrunConfig = new TestRunConfiguration("default"); + string runDeploymentRoot = trxFileHelper.ReplaceInvalidFileNameChars(this.testRun.Name); + TestRunConfiguration testrunConfig = new TestRunConfiguration("default", trxFileHelper); testrunConfig.RunDeploymentRootDirectory = runDeploymentRoot; this.testRun.RunConfiguration = testrunConfig; } diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs index 1b4eacbb5a..d9f479ff68 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs @@ -23,13 +23,15 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.Utility /// internal class Converter { + private readonly TrxFileHelper trxFileHelper; private IFileHelper fileHelper; /// /// Initializes a new instance of the class. /// - public Converter(IFileHelper fileHelper) + public Converter(IFileHelper fileHelper, TrxFileHelper trxFileHelper) { + this.trxFileHelper = trxFileHelper; this.fileHelper = fileHelper; } @@ -68,6 +70,8 @@ public ITestElement ToTestElement( return testElement; } + + /// /// Converts the rockSteady result to unit test result /// @@ -473,7 +477,7 @@ private CollectorDataEntry ToCollectorEntry(ObjectModel.AttachmentSet attachment Debug.Assert(Path.IsPathRooted(sourceFile), "Source file is not rooted"); // copy the source file to the target location - string targetFileName = FileHelper.GetNextIterationFileName(targetDirectory, Path.GetFileName(sourceFile), false); + string targetFileName = trxFileHelper.GetNextIterationFileName(targetDirectory, Path.GetFileName(sourceFile), false); try { @@ -483,7 +487,7 @@ private CollectorDataEntry ToCollectorEntry(ObjectModel.AttachmentSet attachment // (Trx viewer automatically adds In\ to the collected file. string fileName = Path.Combine(Environment.MachineName, Path.GetFileName(targetFileName)); Uri sourceFileUri = new Uri(fileName, UriKind.Relative); - TrxObjectModel.UriDataAttachment dataAttachment = new TrxObjectModel.UriDataAttachment(uriDataAttachment.Description, sourceFileUri); + TrxObjectModel.UriDataAttachment dataAttachment = new TrxObjectModel.UriDataAttachment(uriDataAttachment.Description, sourceFileUri, trxFileHelper); uriDataAttachments.Add(dataAttachment); } @@ -535,7 +539,7 @@ private IList ToResultFiles(ObjectModel.AttachmentSet attachmentSet, Gui Debug.Assert(Path.IsPathRooted(sourceFile), "Source file is not rooted"); // copy the source file to the target location - string targetFileName = FileHelper.GetNextIterationFileName(testResultDirectory, Path.GetFileName(sourceFile), false); + string targetFileName = trxFileHelper.GetNextIterationFileName(testResultDirectory, Path.GetFileName(sourceFile), false); try { @@ -719,8 +723,8 @@ private TrxObjectModel.TestResult CreateTestResult( TestListCategoryId testCategoryId) { return testType.Equals(Constants.OrderedTestType) ? - new TestResultAggregation(runId, testId, executionId, parentExecutionId, resultName, Environment.MachineName, outcome, testType, testCategoryId) : - new UnitTestResult(runId, testId, executionId, parentExecutionId, resultName, Environment.MachineName, outcome, testType, testCategoryId); + new TestResultAggregation(runId, testId, executionId, parentExecutionId, resultName, Environment.MachineName, outcome, testType, testCategoryId, trxFileHelper) : + new UnitTestResult(runId, testId, executionId, parentExecutionId, resultName, Environment.MachineName, outcome, testType, testCategoryId, trxFileHelper); } } diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/FileHelper.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/TrxFileHelper.cs similarity index 85% rename from src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/FileHelper.cs rename to src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/TrxFileHelper.cs index d103506a7d..6461def174 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/FileHelper.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/TrxFileHelper.cs @@ -11,25 +11,26 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.Utility using System.IO; using System.Text; using System.Text.RegularExpressions; - using TrxLoggerResources = Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.Resources.TrxResource; /// /// Helper function to deal with file name. /// - internal static class FileHelper + internal class TrxFileHelper + { private const string RelativeDirectorySeparator = ".."; private static readonly Dictionary InvalidFileNameChars; private static readonly Dictionary AdditionalInvalidFileNameChars; private static readonly Regex ReservedFileNamesRegex = new Regex(@"(?i:^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9]|CLOCK\$)(\..*)?)$"); + private readonly Func TimeProvider; #region Constructors [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Reviewed. Suppression is OK here.")] // Have to init InvalidFileNameChars dynamically. - static FileHelper() + static TrxFileHelper() { // Create a hash table of invalid chars. On Windows, this should match the contents of System.IO.Path.GetInvalidFileNameChars. // See https://github.com/dotnet/coreclr/blob/8e99cd8031b2f568ea69116e7cf96d55e32cb7f5/src/mscorlib/shared/System/IO/Path.Windows.cs#L12-L19 @@ -63,6 +64,13 @@ static FileHelper() AdditionalInvalidFileNameChars.Add(' ', null); } + public TrxFileHelper() : this(() => DateTime.Now) { } + + public TrxFileHelper(Func timeProvider) + { + TimeProvider = timeProvider ?? (() => DateTime.Now); + } + #endregion /// @@ -70,7 +78,7 @@ static FileHelper() /// /// the name of the file /// Replaced string. - public static string ReplaceInvalidFileNameChars(string fileName) + public string ReplaceInvalidFileNameChars(string fileName) { EqtAssert.StringNotNullOrEmpty(fileName, "fileName"); @@ -126,14 +134,53 @@ public static string ReplaceInvalidFileNameChars(string fileName) /// /// The . /// - public static string GetNextIterationFileName(string parentDirectoryName, string originalFileName, bool checkMatchingDirectory) + public string GetNextIterationFileName(string parentDirectoryName, string originalFileName, bool checkMatchingDirectory) { EqtAssert.StringNotNullOrEmpty(parentDirectoryName, "parentDirectoryName"); EqtAssert.StringNotNullOrEmpty(originalFileName, "originalFileName"); return GetNextIterationNameHelper(parentDirectoryName, originalFileName, new FileIterationHelper(checkMatchingDirectory)); } - public static string MakePathRelative(string path, string basePath) + /// + /// Constructs and returns first available timestamped file name. + /// This does not checks for the file permissions. + /// + /// Directory to try timestamped file names in. + /// Filename (with extension) of the desired file. Timestamp will be added just before extension. + /// Timestamp format to be passed into DateTime.ToString method. + /// First available filename with the format of `FileName{Timestamp}.ext`. + /// + /// GetNextTimestampFileName("c:\data", "log.txt", "_yyyyMMddHHmmss") will return "c:\data\log_20200801185521.txt", if available. + /// + public string GetNextTimestampFileName(string directoryName, string fileName, string timestampFormat) + { + EqtAssert.StringNotNullOrEmpty(directoryName, "parentDirectoryName"); + EqtAssert.StringNotNullOrEmpty(fileName, "fileName"); + EqtAssert.StringNotNullOrEmpty(timestampFormat, "timestampFormat"); + + ushort iteration = 0; + var iterationStamp = TimeProvider(); + var fileNamePrefix = Path.GetFileNameWithoutExtension(fileName); + var extension = Path.GetExtension(fileName); + do + { + var tryMe = fileNamePrefix + iterationStamp.ToString(timestampFormat, DateTimeFormatInfo.InvariantInfo) + extension; + + string tryMePath = Path.Combine(directoryName, tryMe); + if (!File.Exists(tryMePath)) + { + return tryMePath; + } + + iterationStamp = iterationStamp.AddSeconds(1); + ++iteration; + } + while (iteration != ushort.MaxValue); + + throw new Exception(string.Format(CultureInfo.CurrentCulture, TrxLoggerResources.Common_CannotGetNextTimestampFileName, fileName, directoryName, timestampFormat)); + } + + public string MakePathRelative(string path, string basePath) { EqtAssert.StringNotNullOrEmpty(path, "path"); diff --git a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs index d9324066b1..c55c000053 100644 --- a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs @@ -4,19 +4,21 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests { + using Microsoft.TestPlatform.Extensions.TrxLogger.Utility; + using Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Linq; + using System.Runtime.CompilerServices; using System.Xml; using System.Xml.Linq; - using Microsoft.TestPlatform.Extensions.TrxLogger.Utility; - using Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger; - using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; using VisualStudio.TestPlatform.ObjectModel; using VisualStudio.TestPlatform.ObjectModel.Client; using VisualStudio.TestPlatform.ObjectModel.Logging; @@ -33,6 +35,9 @@ public class TrxLoggerTests private Dictionary parameters; private static string DefaultTestRunDirectory = Path.GetTempPath(); private static string DefaultLogFileNameParameterValue = "logfilevalue.trx"; + private const string DefaultLogFilePrefixParameterValue = "log_prefix"; + + private const int MultipleLoggerInstanceCount = 2; [TestInitialize] public void Initialize() @@ -634,6 +639,95 @@ public void DefaultTrxFileShouldCreateIfLogFileNameParameterNotPassed() Assert.IsFalse(string.IsNullOrWhiteSpace(this.testableTrxLogger.trxFile)); } + [TestMethod] + public void DefaultTrxFileNameVerification() + { + this.parameters.Remove(TrxLoggerConstants.LogFileNameKey); + this.parameters[TrxLoggerConstants.LogFilePrefixKey] = DefaultLogFilePrefixParameterValue; + + var time = DateTime.Now; + var trxFileHelper = new TrxFileHelper(() => time); + + testableTrxLogger = new TestableTrxLogger(new FileHelper(), trxFileHelper); + testableTrxLogger.Initialize(this.events.Object, this.parameters); + + MakeTestRunComplete(); + + var fileName = Path.GetFileName(testableTrxLogger.trxFile); + var expectedName = $"{DefaultLogFilePrefixParameterValue}{time:_yyyyMMddHHmmss}.trx"; + + Assert.AreEqual(expectedName, fileName, "Trx file name pattern has changed. It should be in the form of prefix_yyyyMMddHHmmss.trx, Azure Devops VSTest task depends on this naming."); + } + + [TestMethod] + public void DefaultTrxFileShouldIterateIfLogFileNameParameterNotPassed() + { + this.parameters.Remove(TrxLoggerConstants.LogFileNameKey); + + var files = TestMultipleTrxLoggers(); + + Assert.AreEqual(MultipleLoggerInstanceCount, files.Length, "All logger instances should get different file names!"); + } + + [TestMethod] + public void TrxFileNameShouldNotIterate() + { + var files = TestMultipleTrxLoggers(); + + Assert.AreEqual(1, files.Length, "All logger instances should get the same file name!"); + } + + [TestMethod] + public void TrxPrefixFileNameShouldIterate() + { + this.parameters.Remove(TrxLoggerConstants.LogFileNameKey); + this.parameters[TrxLoggerConstants.LogFilePrefixKey] = DefaultLogFilePrefixParameterValue; + + var files = TestMultipleTrxLoggers(); + + Assert.AreEqual(MultipleLoggerInstanceCount, files.Length, "All logger instances should get different file names!"); + } + + private string[] TestMultipleTrxLoggers() + { + var files = new string[2]; + + try + { + var time = new DateTime(2020, 1, 1, 0, 0, 0); + + var trxFileHelper = new TrxFileHelper(() => time); + var trxLogger1 = new TestableTrxLogger(new FileHelper(), trxFileHelper); + var trxLogger2 = new TestableTrxLogger(new FileHelper(), trxFileHelper); + + trxLogger1.Initialize(this.events.Object, this.parameters); + trxLogger2.Initialize(this.events.Object, this.parameters); + + MakeTestRunComplete(trxLogger1); + files[0] = trxLogger1.trxFile; + + MakeTestRunComplete(trxLogger2); + files[1] = trxLogger2.trxFile; + } + finally + { + files = files + .Where(i => !string.IsNullOrWhiteSpace(i)) + .Distinct() + .ToArray(); + + foreach (var file in files) + { + if (!string.IsNullOrEmpty(file) && File.Exists(file)) + { + File.Delete(file); + } + } + } + + return files; + } + [TestMethod] public void CustomTrxFileNameShouldConstructFromLogFileParameter() { @@ -642,6 +736,8 @@ public void CustomTrxFileNameShouldConstructFromLogFileParameter() Assert.AreEqual(Path.Combine(TrxLoggerTests.DefaultTestRunDirectory, TrxLoggerTests.DefaultLogFileNameParameterValue), this.testableTrxLogger.trxFile, "Wrong Trx file name"); } + + /// /// Unit test for reading TestCategories from the TestCase which is part of test result. /// @@ -653,7 +749,7 @@ public void GetCustomPropertyValueFromTestCaseShouldReadCategoyrAttributesFromTe testCase1.SetPropertyValue(testProperty, new[] { "ClassLevel", "AsmLevel" }); - var converter = new Converter(new Mock().Object); + var converter = new Converter(new Mock().Object, new TrxFileHelper()); List listCategoriesActual = converter.GetCustomPropertyValueFromTestCase(testCase1, "MSTestDiscoverer.TestCategory"); List listCategoriesExpected = new List(); @@ -809,9 +905,9 @@ private string GetElementValueFromTrx(string trxFileName, string fieldName) using (FileStream file = File.OpenRead(trxFileName)) using (XmlReader reader = XmlReader.Create(file)) { - while(reader.Read()) + while (reader.Read()) { - if(reader.Name.Equals(fieldName) && reader.NodeType == XmlNodeType.Element) + if (reader.Name.Equals(fieldName) && reader.NodeType == XmlNodeType.Element) { return reader.ReadElementContentAsString(); } @@ -849,17 +945,22 @@ private static Mock CreatePassTestResultEventArgsMock(strin return new Mock(passResult); } - private void MakeTestRunComplete() + private void MakeTestRunComplete() => this.MakeTestRunComplete(this.testableTrxLogger); + + private void MakeTestRunComplete(TestableTrxLogger testableTrxLogger) { var pass = TrxLoggerTests.CreatePassTestResultEventArgsMock(); - this.testableTrxLogger.TestResultHandler(new object(), pass.Object); + testableTrxLogger.TestResultHandler(new object(), pass.Object); var testRunCompleteEventArgs = TrxLoggerTests.CreateTestRunCompleteEventArgs(); - this.testableTrxLogger.TestRunCompleteHandler(new object(), testRunCompleteEventArgs); + testableTrxLogger.TestRunCompleteHandler(new object(), testRunCompleteEventArgs); } } internal class TestableTrxLogger : TrxLogger { + public TestableTrxLogger() : base() { } + public TestableTrxLogger(IFileHelper fileHelper, TrxFileHelper trxFileHelper) : base(fileHelper, trxFileHelper) { } + public string trxFile; internal override void PopulateTrxFile(string trxFileName, XmlElement rootElement) { diff --git a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Utility/ConverterTests.cs b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Utility/ConverterTests.cs index 1734b9c15d..0c5dd9789a 100644 --- a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Utility/ConverterTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Utility/ConverterTests.cs @@ -25,11 +25,13 @@ public class ConverterTests { private Converter converter; private Mock fileHelper; + private readonly TrxFileHelper trxFileHelper; public ConverterTests() { this.fileHelper = new Mock(); - this.converter = new Converter(this.fileHelper.Object); + this.trxFileHelper = new TrxFileHelper(); + this.converter = new Converter(this.fileHelper.Object, trxFileHelper); } [TestMethod] @@ -67,7 +69,7 @@ public void ToCollectionEntriesShouldRenameAttachmentUriIfTheAttachmentNameIsSam { ConverterTests.SetupForToCollectionEntries(out var tempDir, out var attachmentSets, out var testRun, out var testResultsDirectory); - this.converter = new Converter(new VisualStudio.TestPlatform.Utilities.Helpers.FileHelper()); + this.converter = new Converter(new FileHelper(), trxFileHelper); List collectorDataEntries = this.converter.ToCollectionEntries(attachmentSets, testRun, testResultsDirectory); Assert.AreEqual($@"{Environment.MachineName}\123.coverage", ((ObjectModel.UriDataAttachment) collectorDataEntries[0].Attachments[0]).Uri.OriginalString); @@ -156,7 +158,7 @@ public void ToResultFilesShouldAddAttachmentsWithRelativeURI() }; var testRun = new TestRun(Guid.NewGuid()); - testRun.RunConfiguration = new TestRunConfiguration("Testrun 1"); + testRun.RunConfiguration = new TestRunConfiguration("Testrun 1", trxFileHelper); attachmentSets[0].Attachments.Add(uriDataAttachment1); var resultFiles = this.converter.ToResultFiles(attachmentSets, testRun, @"c:\temp", null); @@ -214,7 +216,7 @@ private static void SetupForToCollectionEntries(out string tempDir, out List