From 4995c82b875cf365df0fc6dce80280ecc065ae2d Mon Sep 17 00:00:00 2001 From: Giannis Ntovas Date: Tue, 15 Feb 2022 19:40:10 +0200 Subject: [PATCH 1/7] fix same file access exception --- .../HtmlLogger.cs | 38 +++++++++++++++---- .../HtmlLoggerTests.cs | 14 +++---- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs index d0642fc1fe..fde3230a17 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs @@ -37,6 +37,7 @@ public class HtmlLogger : ITestLoggerWithParameters private readonly XmlObjectSerializer _xmlSerializer; private readonly IHtmlTransformer _htmlTransformer; private Dictionary _parametersDictionary; + private static readonly object LockObject = new(); public HtmlLogger() : this(new FileHelper(), new HtmlTransformer(), new DataContractSerializer(typeof(TestRunDetails))) @@ -301,17 +302,18 @@ private void PopulateHtmlFile() Environment.GetEnvironmentVariable("UserName"), Environment.MachineName, FormatDateTimeForRunName(DateTime.Now)); - XmlFilePath = GetFilePath(HtmlLoggerConstants.XmlFileExtension, fileName); + XmlFilePath = GetFilePathAndCreateFile(HtmlLoggerConstants.XmlFileExtension, fileName); - using (var xmlStream = _fileHelper.GetStream(XmlFilePath, FileMode.Create)) + using (var xmlStream = _fileHelper.GetStream(XmlFilePath, FileMode.OpenOrCreate)) { _xmlSerializer.WriteObject(xmlStream, TestRunDetails); } - if (string.IsNullOrEmpty(HtmlFilePath)) - { - HtmlFilePath = GetFilePath(HtmlLoggerConstants.HtmlFileExtension, fileName); - } + HtmlFilePath = string.IsNullOrEmpty(HtmlFilePath) + ? GetFilePathAndCreateFile(HtmlLoggerConstants.HtmlFileExtension, fileName) + : GetFilePathAndCreateFile(HtmlLoggerConstants.HtmlFileExtension, Path.GetFileNameWithoutExtension(HtmlFilePath)); + + HtmlFilePath = GetFilePathAndCreateFile(HtmlLoggerConstants.HtmlFileExtension, Path.GetFileNameWithoutExtension(HtmlFilePath)); _htmlTransformer.Transform(XmlFilePath, HtmlFilePath); } @@ -335,10 +337,25 @@ private void PopulateHtmlFile() ConsoleOutput.Instance.Information(false, htmlFilePathMessage); } - private string GetFilePath(string fileExtension, string fileName) + private string GetFilePathAndCreateFile(string fileExtension, string fileName) { var fullFileFormat = $".{fileExtension}"; - return Path.Combine(TestResultsDirPath, string.Concat("TestResult_", fileName, fullFileFormat)); + string fullFilePath; + for (short i = 0; i < short.MaxValue; i++) + { + var fileNameWithIter = i == 0 ? fileName : GetNextIterationFile(fileName, i); + fullFilePath = Path.Combine(TestResultsDirPath, string.Concat("TestResult_", fileNameWithIter, fullFileFormat)); + lock (LockObject) + { + if (!File.Exists(fullFilePath)) + { + File.Create(fullFilePath); + return fullFilePath; + } + } + } + + throw new Exception($"Cannot generate unique filename for: {fileName}"); } private string FormatDateTimeForRunName(DateTime timeStamp) @@ -346,6 +363,11 @@ private string FormatDateTimeForRunName(DateTime timeStamp) return timeStamp.ToString("yyyyMMdd_HHmmss", DateTimeFormatInfo.InvariantInfo); } + private string GetNextIterationFile(string baseName, short iteration) + { + return $"{Path.GetFileNameWithoutExtension(baseName)}[{iteration}]{(Path.HasExtension(baseName) ? Path.GetExtension(baseName) : string.Empty)}"; + } + /// /// Gives the parent execution id of a TestResult. /// diff --git a/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/HtmlLoggerTests.cs b/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/HtmlLoggerTests.cs index b0d575a510..03f5dbc981 100644 --- a/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/HtmlLoggerTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/HtmlLoggerTests.cs @@ -468,14 +468,14 @@ public void TestCompleteHandlerShouldCreateCustumHtmlFileNameWithLogPrefixNull() var result1 = new ObjectModel.TestResult(testCase1) { Outcome = TestOutcome.Failed }; var resultEventArg1 = new Mock(result1); - _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.Create, FileAccess.ReadWrite)).Callback((x, y, z) => + _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.OpenOrCreate, FileAccess.ReadWrite)).Callback((x, y, z) => { }).Returns(new Mock().Object); _htmlLogger.TestResultHandler(new object(), resultEventArg1.Object); _htmlLogger.TestRunCompleteHandler(new object(), new TestRunCompleteEventArgs(null, false, true, null, null, null, TimeSpan.Zero)); - _mockFileHelper.Verify(x => x.GetStream(It.IsAny(), FileMode.Create, FileAccess.ReadWrite), Times.Once); + _mockFileHelper.Verify(x => x.GetStream(It.IsAny(), FileMode.OpenOrCreate, FileAccess.ReadWrite), Times.Once); } [TestMethod] @@ -514,14 +514,14 @@ public void TestCompleteHandlerShouldCreateFileCorrectly() var result1 = new ObjectModel.TestResult(testCase1) { Outcome = TestOutcome.Failed }; var resultEventArg1 = new Mock(result1); - _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.Create, FileAccess.ReadWrite)).Callback((x, y, z) => + _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.OpenOrCreate, FileAccess.ReadWrite)).Callback((x, y, z) => { }).Returns(new Mock().Object); _htmlLogger.TestResultHandler(new object(), resultEventArg1.Object); _htmlLogger.TestRunCompleteHandler(new object(), new TestRunCompleteEventArgs(null, false, true, null, null, null, TimeSpan.Zero)); - _mockFileHelper.Verify(x => x.GetStream(It.IsAny(), FileMode.Create, FileAccess.ReadWrite), Times.Once); + _mockFileHelper.Verify(x => x.GetStream(It.IsAny(), FileMode.OpenOrCreate, FileAccess.ReadWrite), Times.Once); } [TestMethod] @@ -548,7 +548,7 @@ public void TestCompleteHandlerShouldCallHtmlTransformerCorrectly() var result1 = new ObjectModel.TestResult(testCase1) { Outcome = TestOutcome.Failed }; var resultEventArg1 = new Mock(result1); - _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.Create, FileAccess.ReadWrite)).Callback((x, y, z) => + _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.OpenOrCreate, FileAccess.ReadWrite)).Callback((x, y, z) => { }).Returns(new Mock().Object); @@ -564,7 +564,7 @@ public void TestCompleteHandlerShouldWriteToXmlSerializerCorrectly() var testCase1 = CreateTestCase("TestCase1") ?? throw new ArgumentNullException($"CreateTestCase(\"TestCase1\")"); var result1 = new ObjectModel.TestResult(testCase1) { Outcome = TestOutcome.Failed }; var resultEventArg1 = new Mock(result1); - _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.Create, FileAccess.ReadWrite)).Callback((x, y, z) => + _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.OpenOrCreate, FileAccess.ReadWrite)).Callback((x, y, z) => { }).Returns(new Mock().Object); @@ -579,7 +579,7 @@ public void TestCompleteHandlerShouldWriteToXmlSerializerCorrectly() [TestMethod] public void TestCompleteHandlerShouldNotDivideByZeroWhenThereAre0TestResults() { - _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.Create, FileAccess.ReadWrite)).Callback((x, y, z) => + _mockFileHelper.Setup(x => x.GetStream(It.IsAny(), FileMode.OpenOrCreate, FileAccess.ReadWrite)).Callback((x, y, z) => { }).Returns(new Mock().Object); From ca13bfb52274236923b2faefc1943ae139e6afcf Mon Sep 17 00:00:00 2001 From: Giannis Ntovas Date: Thu, 14 Apr 2022 23:10:04 +0300 Subject: [PATCH 2/7] dont use iteration when HtmlFileName is provided --- .../HtmlLogger.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs index fde3230a17..501845a11b 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs @@ -311,9 +311,7 @@ private void PopulateHtmlFile() HtmlFilePath = string.IsNullOrEmpty(HtmlFilePath) ? GetFilePathAndCreateFile(HtmlLoggerConstants.HtmlFileExtension, fileName) - : GetFilePathAndCreateFile(HtmlLoggerConstants.HtmlFileExtension, Path.GetFileNameWithoutExtension(HtmlFilePath)); - - HtmlFilePath = GetFilePathAndCreateFile(HtmlLoggerConstants.HtmlFileExtension, Path.GetFileNameWithoutExtension(HtmlFilePath)); + : HtmlFilePath; _htmlTransformer.Transform(XmlFilePath, HtmlFilePath); } From 93cc2d8ba3bcaaea9c2cc8b88d9c784706aeee2e Mon Sep 17 00:00:00 2001 From: Giannis Ntovas Date: Mon, 23 May 2022 21:21:13 +0300 Subject: [PATCH 3/7] fixes from review --- .../HtmlLogger.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs index 501845a11b..d9987ecb60 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs @@ -302,16 +302,18 @@ private void PopulateHtmlFile() Environment.GetEnvironmentVariable("UserName"), Environment.MachineName, FormatDateTimeForRunName(DateTime.Now)); - XmlFilePath = GetFilePathAndCreateFile(HtmlLoggerConstants.XmlFileExtension, fileName); + XmlFilePath = _parametersDictionary.TryGetValue(HtmlLoggerConstants.LogFileNameKey, out var string logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue) + ? GetFilePath(HtmlLoggerConstants.XmlFileExtension, fileName) + : GenerateUniqueFile(HtmlLoggerConstants.XmlFileExtension, fileName); using (var xmlStream = _fileHelper.GetStream(XmlFilePath, FileMode.OpenOrCreate)) { _xmlSerializer.WriteObject(xmlStream, TestRunDetails); } - HtmlFilePath = string.IsNullOrEmpty(HtmlFilePath) - ? GetFilePathAndCreateFile(HtmlLoggerConstants.HtmlFileExtension, fileName) - : HtmlFilePath; + HtmlFilePath = _parametersDictionary.TryGetValue(HtmlLoggerConstants.LogFileNameKey, out var string logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue) + ? HtmlFilePath + : GenerateUniqueFile(HtmlLoggerConstants.HtmlFileExtension, fileName); _htmlTransformer.Transform(XmlFilePath, HtmlFilePath); } @@ -335,14 +337,18 @@ private void PopulateHtmlFile() ConsoleOutput.Instance.Information(false, htmlFilePathMessage); } - private string GetFilePathAndCreateFile(string fileExtension, string fileName) + private string GetFilePath(string fileExtension, string fileName) + { + return Path.Combine(TestResultsDirPath, string.Concat("TestResult_", fileName, $".{fileExtension}")); + } + + private string GenerateUniqueFile(string fileExtension, string fileName) { - var fullFileFormat = $".{fileExtension}"; string fullFilePath; for (short i = 0; i < short.MaxValue; i++) { var fileNameWithIter = i == 0 ? fileName : GetNextIterationFile(fileName, i); - fullFilePath = Path.Combine(TestResultsDirPath, string.Concat("TestResult_", fileNameWithIter, fullFileFormat)); + fullFilePath = Path.Combine(TestResultsDirPath, $"TestResult_{fileNameWithIter}.{fileExtension}"); lock (LockObject) { if (!File.Exists(fullFilePath)) @@ -353,7 +359,7 @@ private string GetFilePathAndCreateFile(string fileExtension, string fileName) } } - throw new Exception($"Cannot generate unique filename for: {fileName}"); + throw new Exception($"Cannot generate unique filename for: {fileName} on path: {TestResultsDirPath}"); } private string FormatDateTimeForRunName(DateTime timeStamp) @@ -363,7 +369,7 @@ private string FormatDateTimeForRunName(DateTime timeStamp) private string GetNextIterationFile(string baseName, short iteration) { - return $"{Path.GetFileNameWithoutExtension(baseName)}[{iteration}]{(Path.HasExtension(baseName) ? Path.GetExtension(baseName) : string.Empty)}"; + return Path.GetFileNameWithoutExtension(baseName) + $"[{iteration}]"; } /// From 0b372082acad3a0d7a2d0aeb8daa922a313d60cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 24 May 2022 10:04:10 +0200 Subject: [PATCH 4/7] Fix merge conflicts and apply some style refactorings --- .../HtmlLogger.cs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs index d9987ecb60..8e6d56cda2 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs @@ -36,8 +36,8 @@ public class HtmlLogger : ITestLoggerWithParameters private readonly IFileHelper _fileHelper; private readonly XmlObjectSerializer _xmlSerializer; private readonly IHtmlTransformer _htmlTransformer; - private Dictionary _parametersDictionary; private static readonly object LockObject = new(); + private Dictionary _parametersDictionary; public HtmlLogger() : this(new FileHelper(), new HtmlTransformer(), new DataContractSerializer(typeof(TestRunDetails))) @@ -302,16 +302,16 @@ private void PopulateHtmlFile() Environment.GetEnvironmentVariable("UserName"), Environment.MachineName, FormatDateTimeForRunName(DateTime.Now)); - XmlFilePath = _parametersDictionary.TryGetValue(HtmlLoggerConstants.LogFileNameKey, out var string logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue) - ? GetFilePath(HtmlLoggerConstants.XmlFileExtension, fileName) - : GenerateUniqueFile(HtmlLoggerConstants.XmlFileExtension, fileName); + XmlFilePath = _parametersDictionary.TryGetValue(HtmlLoggerConstants.LogFileNameKey, out var logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue) + ? GetFilePath(HtmlLoggerConstants.XmlFileExtension, fileName) + : GenerateUniqueFile(HtmlLoggerConstants.XmlFileExtension, fileName); using (var xmlStream = _fileHelper.GetStream(XmlFilePath, FileMode.OpenOrCreate)) { _xmlSerializer.WriteObject(xmlStream, TestRunDetails); } - HtmlFilePath = _parametersDictionary.TryGetValue(HtmlLoggerConstants.LogFileNameKey, out var string logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue) + HtmlFilePath = _parametersDictionary.TryGetValue(HtmlLoggerConstants.LogFileNameKey, out logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue) ? HtmlFilePath : GenerateUniqueFile(HtmlLoggerConstants.HtmlFileExtension, fileName); @@ -319,7 +319,7 @@ private void PopulateHtmlFile() } catch (Exception ex) { - EqtTrace.Error("HtmlLogger : Failed to populate html file. Exception : {0}", + EqtTrace.Error("HtmlLogger: Failed to populate html file. Exception: {0}", ex.ToString()); ConsoleOutput.Instance.Error(false, string.Concat(HtmlResource.HtmlLoggerError), ex.Message); return; @@ -339,7 +339,7 @@ private void PopulateHtmlFile() private string GetFilePath(string fileExtension, string fileName) { - return Path.Combine(TestResultsDirPath, string.Concat("TestResult_", fileName, $".{fileExtension}")); + return Path.Combine(TestResultsDirPath, $"TestResult_{fileName}.{fileExtension}"); } private string GenerateUniqueFile(string fileExtension, string fileName) @@ -359,7 +359,10 @@ private string GenerateUniqueFile(string fileExtension, string fileName) } } - throw new Exception($"Cannot generate unique filename for: {fileName} on path: {TestResultsDirPath}"); + throw new InvalidOperationException($"Cannot generate a unique filename for '{fileName}' on path '{TestResultsDirPath}'."); + + static string GetNextIterationFile(string baseName, short iteration) + => Path.GetFileNameWithoutExtension(baseName) + $"[{iteration}]"; } private string FormatDateTimeForRunName(DateTime timeStamp) @@ -367,11 +370,6 @@ private string FormatDateTimeForRunName(DateTime timeStamp) return timeStamp.ToString("yyyyMMdd_HHmmss", DateTimeFormatInfo.InvariantInfo); } - private string GetNextIterationFile(string baseName, short iteration) - { - return Path.GetFileNameWithoutExtension(baseName) + $"[{iteration}]"; - } - /// /// Gives the parent execution id of a TestResult. /// From 7d5782de5b6138d27dae919d479c553b519908ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 24 May 2022 13:51:03 +0200 Subject: [PATCH 5/7] Fix behavior --- .../HtmlLogger.cs | 28 +++++++------------ .../Resources/Resources.Designer.cs | 11 +++++++- .../Resources/Resources.resx | 3 ++ .../HtmlLoggerTests.cs | 8 +++--- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs index 8e6d56cda2..1cc229973a 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs @@ -302,18 +302,18 @@ private void PopulateHtmlFile() Environment.GetEnvironmentVariable("UserName"), Environment.MachineName, FormatDateTimeForRunName(DateTime.Now)); - XmlFilePath = _parametersDictionary.TryGetValue(HtmlLoggerConstants.LogFileNameKey, out var logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue) - ? GetFilePath(HtmlLoggerConstants.XmlFileExtension, fileName) - : GenerateUniqueFile(HtmlLoggerConstants.XmlFileExtension, fileName); + XmlFilePath = GenerateUniqueFilePath(fileName, HtmlLoggerConstants.XmlFileExtension); using (var xmlStream = _fileHelper.GetStream(XmlFilePath, FileMode.OpenOrCreate)) { _xmlSerializer.WriteObject(xmlStream, TestRunDetails); } - HtmlFilePath = _parametersDictionary.TryGetValue(HtmlLoggerConstants.LogFileNameKey, out logFileNameValue) && !string.IsNullOrWhiteSpace(logFileNameValue) - ? HtmlFilePath - : GenerateUniqueFile(HtmlLoggerConstants.HtmlFileExtension, fileName); + HtmlFilePath = GenerateUniqueFilePath( + string.IsNullOrEmpty(HtmlFilePath) + ? fileName + : Path.GetFileNameWithoutExtension(HtmlFilePath), + HtmlLoggerConstants.HtmlFileExtension); _htmlTransformer.Transform(XmlFilePath, HtmlFilePath); } @@ -321,7 +321,7 @@ private void PopulateHtmlFile() { EqtTrace.Error("HtmlLogger: Failed to populate html file. Exception: {0}", ex.ToString()); - ConsoleOutput.Instance.Error(false, string.Concat(HtmlResource.HtmlLoggerError), ex.Message); + ConsoleOutput.Instance.Error(false, HtmlResource.HtmlLoggerError, ex.Message); return; } finally @@ -337,17 +337,12 @@ private void PopulateHtmlFile() ConsoleOutput.Instance.Information(false, htmlFilePathMessage); } - private string GetFilePath(string fileExtension, string fileName) - { - return Path.Combine(TestResultsDirPath, $"TestResult_{fileName}.{fileExtension}"); - } - - private string GenerateUniqueFile(string fileExtension, string fileName) + private string GenerateUniqueFilePath(string fileName, string fileExtension) { string fullFilePath; for (short i = 0; i < short.MaxValue; i++) { - var fileNameWithIter = i == 0 ? fileName : GetNextIterationFile(fileName, i); + var fileNameWithIter = i == 0 ? fileName : Path.GetFileNameWithoutExtension(fileName) + $"[{i}]"; fullFilePath = Path.Combine(TestResultsDirPath, $"TestResult_{fileNameWithIter}.{fileExtension}"); lock (LockObject) { @@ -359,10 +354,7 @@ private string GenerateUniqueFile(string fileExtension, string fileName) } } - throw new InvalidOperationException($"Cannot generate a unique filename for '{fileName}' on path '{TestResultsDirPath}'."); - - static string GetNextIterationFile(string baseName, short iteration) - => Path.GetFileNameWithoutExtension(baseName) + $"[{iteration}]"; + throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, HtmlResource.CannotGenerateUniqueFilePath, fileName, TestResultsDirPath)); } private string FormatDateTimeForRunName(DateTime timeStamp) diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/Resources.Designer.cs index 4c39a8ad6e..0b4afa76d8 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/Resources.Designer.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Extensions.HtmlLogger.Resources { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -60,6 +60,15 @@ internal Resources() { } } + /// + /// Looks up a localized string similar to Cannot generate a unique file name for name '{0}' on path '{1}'.. + /// + internal static string CannotGenerateUniqueFilePath { + get { + return ResourceManager.GetString("CannotGenerateUniqueFilePath", resourceCulture); + } + } + /// /// Looks up a localized string similar to Html test results file : {0}. /// diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/Resources.resx b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/Resources.resx index 8182657a80..8e0937eb71 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/Resources.resx +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/Resources.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Html test results file : {0} diff --git a/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/HtmlLoggerTests.cs b/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/HtmlLoggerTests.cs index 03f5dbc981..41bb939f41 100644 --- a/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/HtmlLoggerTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/HtmlLoggerTests.cs @@ -396,7 +396,7 @@ public void TestCompleteHandlerShouldKeepTackOfSummary() } [TestMethod] - public void TestCompleteHandlerShouldCreateCustumHtmlFileNamewithLogFileNameKey() + public void TestCompleteHandlerShouldCreateCustomHtmlFileNamewithLogFileNameKey() { var parameters = new Dictionary { @@ -415,7 +415,7 @@ public void TestCompleteHandlerShouldCreateCustumHtmlFileNamewithLogFileNameKey( } [TestMethod] - public void TestCompleteHandlerShouldCreateCustumHtmlFileNameWithLogPrefix() + public void TestCompleteHandlerShouldCreateCustomHtmlFileNameWithLogPrefix() { var parameters = new Dictionary { @@ -435,7 +435,7 @@ public void TestCompleteHandlerShouldCreateCustumHtmlFileNameWithLogPrefix() } [TestMethod] - public void TestCompleteHandlerShouldCreateCustumHtmlFileNameWithLogPrefixIfTargetFrameworkIsNull() + public void TestCompleteHandlerShouldCreateCustomHtmlFileNameWithLogPrefixIfTargetFrameworkIsNull() { var parameters = new Dictionary { @@ -455,7 +455,7 @@ public void TestCompleteHandlerShouldCreateCustumHtmlFileNameWithLogPrefixIfTarg } [TestMethod] - public void TestCompleteHandlerShouldCreateCustumHtmlFileNameWithLogPrefixNull() + public void TestCompleteHandlerShouldCreateCustomHtmlFileNameWithLogPrefixNull() { var parameters = new Dictionary { From 41b6ec73a1d145144795a0cd79dc712a973f60aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 25 May 2022 13:44:39 +0200 Subject: [PATCH 6/7] Fix broken tests --- .../HtmlLogger.cs | 11 +++++------ .../Resources/xlf/Resources.cs.xlf | 5 +++++ .../Resources/xlf/Resources.de.xlf | 5 +++++ .../Resources/xlf/Resources.es.xlf | 5 +++++ .../Resources/xlf/Resources.fr.xlf | 5 +++++ .../Resources/xlf/Resources.it.xlf | 5 +++++ .../Resources/xlf/Resources.ja.xlf | 5 +++++ .../Resources/xlf/Resources.ko.xlf | 5 +++++ .../Resources/xlf/Resources.pl.xlf | 5 +++++ .../Resources/xlf/Resources.pt-BR.xlf | 5 +++++ .../Resources/xlf/Resources.ru.xlf | 5 +++++ .../Resources/xlf/Resources.tr.xlf | 5 +++++ .../Resources/xlf/Resources.xlf | 5 +++++ .../Resources/xlf/Resources.zh-Hans.xlf | 5 +++++ .../Resources/xlf/Resources.zh-Hant.xlf | 5 +++++ .../LoggerTests.cs | 2 +- 16 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs index 1cc229973a..cc40a450e2 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs @@ -309,11 +309,10 @@ private void PopulateHtmlFile() _xmlSerializer.WriteObject(xmlStream, TestRunDetails); } - HtmlFilePath = GenerateUniqueFilePath( - string.IsNullOrEmpty(HtmlFilePath) - ? fileName - : Path.GetFileNameWithoutExtension(HtmlFilePath), - HtmlLoggerConstants.HtmlFileExtension); + if (string.IsNullOrEmpty(HtmlFilePath)) + { + HtmlFilePath = GenerateUniqueFilePath(fileName, HtmlLoggerConstants.HtmlFileExtension); + } _htmlTransformer.Transform(XmlFilePath, HtmlFilePath); } @@ -348,7 +347,7 @@ private string GenerateUniqueFilePath(string fileName, string fileExtension) { if (!File.Exists(fullFilePath)) { - File.Create(fullFilePath); + using var _ = File.Create(fullFilePath); return fullFilePath; } } diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.cs.xlf index 797ee003e0..54c5187604 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.cs.xlf @@ -17,6 +17,11 @@ Parametry LogFileName a LogFilePrefix nelze uvést společně. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.de.xlf index 0036fb22b0..a5ba0d63c3 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.de.xlf @@ -17,6 +17,11 @@ Die Parameter "LogFileName" und "LogFilePrefix" können nicht zusammen angegeben werden. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.es.xlf index 8db3c86978..717bccf9c2 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.es.xlf @@ -17,6 +17,11 @@ Los parámetros LogFileName y LogFilePrefix no se pueden proporcionar juntos. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.fr.xlf index 5139854891..771bffc718 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.fr.xlf @@ -17,6 +17,11 @@ Les paramètres LogFileName et LogFilePrefix ne peuvent pas être donnés ensemble. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.it.xlf index 56e5a0fd34..36bf938ebe 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.it.xlf @@ -17,6 +17,11 @@ Non è possibile specificare insieme i parametri LogFileName e LogFilePrefix. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ja.xlf index 91d9b72ac7..8f3e4c459b 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ja.xlf @@ -17,6 +17,11 @@ パラメーター LogFileName と LogFilePrefix を同時に指定することはできません。 + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ko.xlf index fd2d309453..ccb0d4d184 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ko.xlf @@ -17,6 +17,11 @@ LogFileName 및 LogFilePrefix 매개 변수는 함께 제공할 수 없습니다. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.pl.xlf index 73d37a49e0..c26718ad41 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.pl.xlf @@ -17,6 +17,11 @@ Parametry LogFileName i LogFilePrefix nie mogą być podawane razem. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.pt-BR.xlf index aea6458fbc..9c133256d2 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.pt-BR.xlf @@ -17,6 +17,11 @@ Os parâmetros LogFileName e LogFilePrefix não podem ser usados juntos. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ru.xlf index a436d171f3..01a03b47e4 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.ru.xlf @@ -17,6 +17,11 @@ Параметры LogFileName и LogFilePrefix не могут использоваться вместе. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.tr.xlf index 864e4a78cd..c05705f1af 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.tr.xlf @@ -17,6 +17,11 @@ LogFileName ve LogFilePrefix parametreleri birlikte kullanılamaz. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.xlf index 7ac0207fec..e67fc3100b 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.xlf @@ -17,6 +17,11 @@ The parameters LogFileName and LogFilePrefix cannot be given together. + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.zh-Hans.xlf index d1de0ea107..3afa6f45ec 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.zh-Hans.xlf @@ -17,6 +17,11 @@ 参数 LogFileName 和 LogFilePrefix 不能一起使用。 + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.zh-Hant.xlf index e3c03e3c9b..05cef9b414 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/Resources/xlf/Resources.zh-Hant.xlf @@ -17,6 +17,11 @@ 不能同時指定參數 LogFileName 和 LogFilePrefix。 + + Cannot generate a unique file name for name '{0}' on path '{1}'. + Cannot generate a unique file name for name '{0}' on path '{1}'. + + \ No newline at end of file diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/LoggerTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/LoggerTests.cs index e9e30d8fdc..f48ba219a2 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/LoggerTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/LoggerTests.cs @@ -107,7 +107,7 @@ public void HtmlLoggerWithExecutorUriShouldProperlyOverwriteFile(RunnerInfo runn var arguments = PrepareArguments(GetSampleTestAssembly(), GetTestAdapterPath(), string.Empty, FrameworkArgValue, runnerInfo.InIsolationValue, TempDirectory.Path); var htmlFileName = "TestResults.html"; - arguments = string.Concat(arguments, $" /logger:\"logger://Microsoft/TestPlatform/htmlLogger/v1;LogFileName{htmlFileName}\""); + arguments = string.Concat(arguments, $" /logger:\"logger://Microsoft/TestPlatform/htmlLogger/v1;LogFileName={htmlFileName}\""); InvokeVsTest(arguments); arguments = PrepareArguments(GetSampleTestAssembly(), GetTestAdapterPath(), string.Empty, FrameworkArgValue, runnerInfo.InIsolationValue, TempDirectory.Path); From 8a42f01d83aa5dbf41931733a3a0ea4e548e81b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 26 May 2022 11:00:57 +0200 Subject: [PATCH 7/7] Rename lock --- .../HtmlLogger.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs index cc40a450e2..b7dd84dddd 100644 --- a/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.HtmlLogger/HtmlLogger.cs @@ -36,7 +36,7 @@ public class HtmlLogger : ITestLoggerWithParameters private readonly IFileHelper _fileHelper; private readonly XmlObjectSerializer _xmlSerializer; private readonly IHtmlTransformer _htmlTransformer; - private static readonly object LockObject = new(); + private static readonly object FileCreateLockObject = new(); private Dictionary _parametersDictionary; public HtmlLogger() @@ -343,7 +343,7 @@ private string GenerateUniqueFilePath(string fileName, string fileExtension) { var fileNameWithIter = i == 0 ? fileName : Path.GetFileNameWithoutExtension(fileName) + $"[{i}]"; fullFilePath = Path.Combine(TestResultsDirPath, $"TestResult_{fileNameWithIter}.{fileExtension}"); - lock (LockObject) + lock (FileCreateLockObject) { if (!File.Exists(fullFilePath)) {