From fe44944a0ddfa794a8f5a7e974ac8aec6a8422c0 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 31 Dec 2021 15:03:27 -0700 Subject: [PATCH 1/6] diagnostics --- .../tests/File/EncryptDecrypt.cs | 94 ++++++++++++++++++- 1 file changed, 90 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs index 12299fad33fcf5..6f7c8d5a7475d1 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs @@ -1,17 +1,28 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.DotNet.XUnitExtensions; using System.Diagnostics; +using System.Diagnostics.Eventing.Reader; using System.Security; +using System.ServiceProcess; using Xunit; +using Xunit.Abstractions; namespace System.IO.Tests { [ActiveIssue("https://github.com/dotnet/runtime/issues/34582", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public class EncryptDecrypt : FileSystemTest { + private readonly ITestOutputHelper _output; + + public EncryptDecrypt(ITestOutputHelper output) + { + _output = output; + } + [Fact] - public static void NullArg_ThrowsException() + public void NullArg_ThrowsException() { AssertExtensions.Throws("path", () => File.Encrypt(null)); AssertExtensions.Throws("path", () => File.Decrypt(null)); @@ -19,7 +30,7 @@ public static void NullArg_ThrowsException() [SkipOnTargetFramework(TargetFrameworkMonikers.Netcoreapp)] [Fact] - public static void EncryptDecrypt_NotSupported() + public void EncryptDecrypt_NotSupported() { Assert.Throws(() => File.Encrypt("path")); Assert.Throws(() => File.Decrypt("path")); @@ -29,7 +40,7 @@ public static void EncryptDecrypt_NotSupported() // because EFS (Encrypted File System), its underlying technology, is not available on these operating systems. [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer), nameof(PlatformDetection.IsNotWindowsHomeEdition))] [PlatformSpecific(TestPlatforms.Windows)] - public static void EncryptDecrypt_Read() + public void EncryptDecrypt_Read() { string tmpFileName = Path.GetTempFileName(); string textContentToEncrypt = "Content to encrypt"; @@ -48,7 +59,13 @@ public static void EncryptDecrypt_Read() { // Ignore ERROR_NOT_FOUND 1168 (0x490). It is reported when EFS is disabled by domain policy. // Ignore ERROR_NO_USER_KEYS (0x1776). This occurs when no user key exists to encrypt with. - return; + throw new SkipTestException($"Encrypt not available. Error 0x{e.HResult:X}"); + } + catch (IOException e) + { + _output.WriteLine($"Encrypt failed with {e.Message}. Logging some EFS diagnostics.."); + LogEFSDiagnostics(); + throw; } Assert.Equal(fileContentRead, File.ReadAllText(tmpFileName)); @@ -63,5 +80,74 @@ public static void EncryptDecrypt_Read() File.Delete(tmpFileName); } } + + private void LogEFSDiagnostics() + { + try + { + using var sc = new ServiceController("EFS"); + _output.WriteLine($"EFS service is: {sc.Status}"); + if (sc.Status != ServiceControllerStatus.Running) + { + _output.WriteLine("Trying to start EFS service"); + sc.Start(); + _output.WriteLine($"EFS service is now: {sc.Status}"); + } + } + catch(Exception e) + { + _output.WriteLine(e.ToString()); + } + + var hours = 1; // how many hours to look backwards + var query = @$" + + + + + + + *[System[TimeCreated[timediff(@SystemTime) >= {hours * 60 * 60 * 1000L}]]] + + + "; + + var eventQuery = new EventLogQuery("System", PathType.LogName, query); + + var eventReader = new EventLogReader(eventQuery); + + EventRecord record = eventReader.ReadEvent(); + var garbage = new string[] { "Background Intelligent", "Intel", "Defender", "Intune", "BITS", "NetBT"}; + + _output.WriteLine("===== Dumping recent relevant events: ====="); + while (record != null) + { + string description = ""; + try + { + description = record.FormatDescription(); + } + catch (EventLogException) { } + + foreach (string term in garbage) + { + if (description.Contains(term, StringComparison.OrdinalIgnoreCase)) + goto next; + } + + _output.WriteLine($"{record.TimeCreated} {record.ProviderName} [{record.LevelDisplayName} {record.Id}] {description.Replace("\r\n", " ")}"); + + next: + record = eventReader.ReadEvent(); + } + + _output.WriteLine("==== Finished dumping ====="); + } } } From e3098fcb7b228b70e5aa85115f39867e204a3fe5 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 31 Dec 2021 15:41:19 -0700 Subject: [PATCH 2/6] make outerloop --- src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs index 6f7c8d5a7475d1..f94131d6d1d0fa 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs @@ -40,6 +40,7 @@ public void EncryptDecrypt_NotSupported() // because EFS (Encrypted File System), its underlying technology, is not available on these operating systems. [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer), nameof(PlatformDetection.IsNotWindowsHomeEdition))] [PlatformSpecific(TestPlatforms.Windows)] + [OuterLoop] // Occasional failures: https://github.com/dotnet/runtime/issues/12339 public void EncryptDecrypt_Read() { string tmpFileName = Path.GetTempFileName(); From d2bba527161ac4fcbf611f7714fd2fbb42850519 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Sat, 1 Jan 2022 16:54:06 -0700 Subject: [PATCH 3/6] fix linux build --- .../tests/File/EncryptDecrypt.Windows.cs | 85 +++++++++++++++++++ .../tests/File/EncryptDecrypt.cs | 73 +--------------- .../tests/System.IO.FileSystem.Tests.csproj | 1 + 3 files changed, 89 insertions(+), 70 deletions(-) create mode 100644 src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs new file mode 100644 index 00000000000000..c981c5d21ef115 --- /dev/null +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.DotNet.XUnitExtensions; +using System.Diagnostics; +using System.Diagnostics.Eventing.Reader; +using System.Security; +using System.ServiceProcess; +using Xunit; +using Xunit.Abstractions; + +namespace System.IO.Tests +{ + public partial class EncryptDecrypt + { + partial void LogEFSDiagnostics() + { + try + { + using var sc = new ServiceController("EFS"); + _output.WriteLine($"EFS service is: {sc.Status}"); + if (sc.Status != ServiceControllerStatus.Running) + { + _output.WriteLine("Trying to start EFS service"); + sc.Start(); + _output.WriteLine($"EFS service is now: {sc.Status}"); + } + } + catch(Exception e) + { + _output.WriteLine(e.ToString()); + } + + var hours = 1; // how many hours to look backwards + var query = @$" + + + + + + + *[System[TimeCreated[timediff(@SystemTime) >= {hours * 60 * 60 * 1000L}]]] + + + "; + + var eventQuery = new EventLogQuery("System", PathType.LogName, query); + + var eventReader = new EventLogReader(eventQuery); + + EventRecord record = eventReader.ReadEvent(); + var garbage = new string[] { "Background Intelligent", "Intel", "Defender", "Intune", "BITS", "NetBT"}; + + _output.WriteLine("===== Dumping recent relevant events: ====="); + while (record != null) + { + string description = ""; + try + { + description = record.FormatDescription(); + } + catch (EventLogException) { } + + foreach (string term in garbage) + { + if (description.Contains(term, StringComparison.OrdinalIgnoreCase)) + goto next; + } + + _output.WriteLine($"{record.TimeCreated} {record.ProviderName} [{record.LevelDisplayName} {record.Id}] {description.Replace("\r\n", " ")}"); + + next: + record = eventReader.ReadEvent(); + } + + _output.WriteLine("==== Finished dumping ====="); + } + } +} diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs index f94131d6d1d0fa..9c60a03f4699ef 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs @@ -12,7 +12,7 @@ namespace System.IO.Tests { [ActiveIssue("https://github.com/dotnet/runtime/issues/34582", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] - public class EncryptDecrypt : FileSystemTest + public partial class EncryptDecrypt : FileSystemTest { private readonly ITestOutputHelper _output; @@ -64,7 +64,7 @@ public void EncryptDecrypt_Read() } catch (IOException e) { - _output.WriteLine($"Encrypt failed with {e.Message}. Logging some EFS diagnostics.."); + _output.WriteLine($"Encrypt failed with {e.Message} 0x{e.HResult:X}"); LogEFSDiagnostics(); throw; } @@ -82,73 +82,6 @@ public void EncryptDecrypt_Read() } } - private void LogEFSDiagnostics() - { - try - { - using var sc = new ServiceController("EFS"); - _output.WriteLine($"EFS service is: {sc.Status}"); - if (sc.Status != ServiceControllerStatus.Running) - { - _output.WriteLine("Trying to start EFS service"); - sc.Start(); - _output.WriteLine($"EFS service is now: {sc.Status}"); - } - } - catch(Exception e) - { - _output.WriteLine(e.ToString()); - } - - var hours = 1; // how many hours to look backwards - var query = @$" - - - - - - - *[System[TimeCreated[timediff(@SystemTime) >= {hours * 60 * 60 * 1000L}]]] - - - "; - - var eventQuery = new EventLogQuery("System", PathType.LogName, query); - - var eventReader = new EventLogReader(eventQuery); - - EventRecord record = eventReader.ReadEvent(); - var garbage = new string[] { "Background Intelligent", "Intel", "Defender", "Intune", "BITS", "NetBT"}; - - _output.WriteLine("===== Dumping recent relevant events: ====="); - while (record != null) - { - string description = ""; - try - { - description = record.FormatDescription(); - } - catch (EventLogException) { } - - foreach (string term in garbage) - { - if (description.Contains(term, StringComparison.OrdinalIgnoreCase)) - goto next; - } - - _output.WriteLine($"{record.TimeCreated} {record.ProviderName} [{record.LevelDisplayName} {record.Id}] {description.Replace("\r\n", " ")}"); - - next: - record = eventReader.ReadEvent(); - } - - _output.WriteLine("==== Finished dumping ====="); - } + partial void LogEFSDiagnostics(); // no-op on Unix currently } } diff --git a/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj b/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj index 7c219c593107bf..83f7bf47ea78e0 100644 --- a/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj +++ b/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj @@ -76,6 +76,7 @@ + From 579ef5be313aea703818e2225b70cb7714a90cf3 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Sat, 1 Jan 2022 17:00:04 -0700 Subject: [PATCH 4/6] space --- .../System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs index c981c5d21ef115..4d464ce8719248 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs @@ -26,7 +26,7 @@ partial void LogEFSDiagnostics() _output.WriteLine($"EFS service is now: {sc.Status}"); } } - catch(Exception e) + catch (Exception e) { _output.WriteLine(e.ToString()); } From 0fc890212c36ba5ed27733150ad3b3466ef6c893 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Mon, 3 Jan 2022 09:17:34 -0700 Subject: [PATCH 5/6] feedback --- .../tests/File/EncryptDecrypt.Windows.cs | 14 +++++++------- .../tests/File/EncryptDecrypt.cs | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs index 4d464ce8719248..853c195a9368a1 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs @@ -4,6 +4,7 @@ using Microsoft.DotNet.XUnitExtensions; using System.Diagnostics; using System.Diagnostics.Eventing.Reader; +using System.Linq; using System.Security; using System.ServiceProcess; using Xunit; @@ -13,7 +14,7 @@ namespace System.IO.Tests { public partial class EncryptDecrypt { - partial void LogEFSDiagnostics() + partial void EnsureEFSServiceStarted() { try { @@ -30,7 +31,10 @@ partial void LogEFSDiagnostics() { _output.WriteLine(e.ToString()); } + } + partial void LogEFSDiagnostics() + { var hours = 1; // how many hours to look backwards var query = @$" @@ -67,15 +71,11 @@ partial void LogEFSDiagnostics() } catch (EventLogException) { } - foreach (string term in garbage) + if (!garbage.Any(term => description.Contains(term, StringComparison.OrdinalIgnoreCase))) { - if (description.Contains(term, StringComparison.OrdinalIgnoreCase)) - goto next; + _output.WriteLine($"{record.TimeCreated} {record.ProviderName} [{record.LevelDisplayName} {record.Id}] {description.Replace("\r\n", " ")}"); } - _output.WriteLine($"{record.TimeCreated} {record.ProviderName} [{record.LevelDisplayName} {record.Id}] {description.Replace("\r\n", " ")}"); - - next: record = eventReader.ReadEvent(); } diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs index 9c60a03f4699ef..c4d34c320668ef 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs @@ -51,6 +51,8 @@ public void EncryptDecrypt_Read() string fileContentRead = File.ReadAllText(tmpFileName); Assert.Equal(textContentToEncrypt, fileContentRead); + EnsureEFSServiceStarted(); + try { File.Encrypt(tmpFileName); @@ -82,6 +84,8 @@ public void EncryptDecrypt_Read() } } + partial void EnsureEFSServiceStarted(); // no-op on Unix + partial void LogEFSDiagnostics(); // no-op on Unix currently } } From 30abfd4e788d885a0158e45b62c7a145cc830273 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Mon, 3 Jan 2022 12:16:09 -0700 Subject: [PATCH 6/6] Apply suggestions from code review Co-authored-by: Stephen Toub --- .../tests/File/EncryptDecrypt.Windows.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs index 853c195a9368a1..015ba30b6ad7c1 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.Windows.cs @@ -35,8 +35,8 @@ partial void EnsureEFSServiceStarted() partial void LogEFSDiagnostics() { - var hours = 1; // how many hours to look backwards - var query = @$" + int hours = 1; // how many hours to look backwards + string query = @$"