Files
sharpcompress/tests/SharpCompress.Test/TempDirectory.cs
2026-05-14 08:26:02 +01:00

84 lines
2.4 KiB
C#

using System;
using System.IO;
using System.Threading.Tasks;
namespace SharpCompress.Test;
internal sealed class TempDirectory : IAsyncDisposable
{
private const int MaxDeleteAttempts = 5;
private static readonly TimeSpan DeleteRetryDelay = TimeSpan.FromMilliseconds(100);
public TempDirectory(string prefix)
{
Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"{prefix}.{Guid.NewGuid():N}");
Directory.CreateDirectory(Path);
}
public string Path { get; }
public string GetDirectory(string name)
{
var path = System.IO.Path.Combine(Path, name);
Directory.CreateDirectory(path);
return path;
}
public string CreateDirectory(string name)
{
var path = System.IO.Path.Combine(Path, name, System.IO.Path.GetRandomFileName());
Directory.CreateDirectory(path);
return path;
}
public void ResetDirectory(string name)
{
DeleteDirectory(System.IO.Path.Combine(Path, name));
Directory.CreateDirectory(System.IO.Path.Combine(Path, name));
}
public async ValueTask DisposeAsync()
{
for (var attempt = 1; attempt <= MaxDeleteAttempts; attempt++)
{
try
{
DeleteDirectory(Path);
if (Directory.Exists(Path))
{
throw new IOException(
$"Temp test directory '{Path}' still exists after deletion."
);
}
return;
}
catch (Exception ex)
when (IsRetryableDeleteException(ex) && attempt < MaxDeleteAttempts)
{
await Task.Delay(DeleteRetryDelay).ConfigureAwait(false);
}
catch (Exception ex) when (IsRetryableDeleteException(ex))
{
throw new InvalidOperationException(
$"Failed to clean up temp test directory '{Path}'.",
ex
);
}
}
throw new InvalidOperationException($"Temp test directory '{Path}' was not cleaned up.");
}
private static void DeleteDirectory(string path)
{
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
}
private static bool IsRetryableDeleteException(Exception ex) =>
ex is IOException or UnauthorizedAccessException;
}