Skip to content

Commit

Permalink
Add some diagnostics for EFS tests (dotnet#63243)
Browse files Browse the repository at this point in the history
* diagnostics

* make outerloop

* fix linux build

* space

* feedback

* Apply suggestions from code review

Co-authored-by: Stephen Toub <[email protected]>

Co-authored-by: Stephen Toub <[email protected]>
  • Loading branch information
danmoseley and stephentoub authored Jan 4, 2022
1 parent e789b4e commit 13305d0
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -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.Linq;
using System.Security;
using System.ServiceProcess;
using Xunit;
using Xunit.Abstractions;

namespace System.IO.Tests
{
public partial class EncryptDecrypt
{
partial void EnsureEFSServiceStarted()
{
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());
}
}

partial void LogEFSDiagnostics()
{
int hours = 1; // how many hours to look backwards
string query = @$"
<QueryList>
<Query Id='0' Path='System'>
<Select Path='System'>
*[System[Provider/@Name='Server']]
</Select>
<Select Path='System'>
*[System[Provider/@Name='Service Control Manager']]
</Select>
<Select Path='System'>
*[System[Provider/@Name='Microsoft-Windows-EFS']]
</Select>
<Suppress Path='System'>
*[System[TimeCreated[timediff(@SystemTime) &gt;= {hours * 60 * 60 * 1000L}]]]
</Suppress>
</Query>
</QueryList> ";

var eventQuery = new EventLogQuery("System", PathType.LogName, query);

using 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) { }

if (!garbage.Any(term => description.Contains(term, StringComparison.OrdinalIgnoreCase)))
{
_output.WriteLine($"{record.TimeCreated} {record.ProviderName} [{record.LevelDisplayName} {record.Id}] {description.Replace("\r\n", " ")}");
}

record = eventReader.ReadEvent();
}

_output.WriteLine("==== Finished dumping =====");
}
}
}
34 changes: 29 additions & 5 deletions src/libraries/System.IO.FileSystem/tests/File/EncryptDecrypt.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
// 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
public partial 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<ArgumentNullException>("path", () => File.Encrypt(null));
AssertExtensions.Throws<ArgumentNullException>("path", () => File.Decrypt(null));
}

[SkipOnTargetFramework(TargetFrameworkMonikers.Netcoreapp)]
[Fact]
public static void EncryptDecrypt_NotSupported()
public void EncryptDecrypt_NotSupported()
{
Assert.Throws<PlatformNotSupportedException>(() => File.Encrypt("path"));
Assert.Throws<PlatformNotSupportedException>(() => File.Decrypt("path"));
Expand All @@ -29,7 +40,8 @@ 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()
[OuterLoop] // Occasional failures: https://github.com/dotnet/runtime/issues/12339
public void EncryptDecrypt_Read()
{
string tmpFileName = Path.GetTempFileName();
string textContentToEncrypt = "Content to encrypt";
Expand All @@ -39,6 +51,8 @@ public static void EncryptDecrypt_Read()
string fileContentRead = File.ReadAllText(tmpFileName);
Assert.Equal(textContentToEncrypt, fileContentRead);

EnsureEFSServiceStarted();

try
{
File.Encrypt(tmpFileName);
Expand All @@ -48,7 +62,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} 0x{e.HResult:X}");
LogEFSDiagnostics();
throw;
}

Assert.Equal(fileContentRead, File.ReadAllText(tmpFileName));
Expand All @@ -63,5 +83,9 @@ public static void EncryptDecrypt_Read()
File.Delete(tmpFileName);
}
}

partial void EnsureEFSServiceStarted(); // no-op on Unix

partial void LogEFSDiagnostics(); // no-op on Unix currently
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Compile Include="Directory\Delete.Windows.cs" />
<Compile Include="File\EncryptDecrypt.Windows.cs" />
<Compile Include="FileSystemTest.Windows.cs" />
<Compile Include="FileStream\ctor_options.Windows.cs" />
<Compile Include="FileStream\FileStreamConformanceTests.Windows.cs" />
Expand Down

0 comments on commit 13305d0

Please sign in to comment.