2023-09-11 08:43:27 +00:00
|
|
|
|
using Logging;
|
|
|
|
|
using NUnit.Framework;
|
|
|
|
|
using Utils;
|
|
|
|
|
|
|
|
|
|
namespace FileUtils
|
|
|
|
|
{
|
2023-09-12 11:32:06 +00:00
|
|
|
|
public class TrackedFile
|
2023-09-11 08:43:27 +00:00
|
|
|
|
{
|
2023-09-12 08:31:55 +00:00
|
|
|
|
private readonly ILog log;
|
2023-09-11 08:43:27 +00:00
|
|
|
|
|
2023-09-12 11:32:06 +00:00
|
|
|
|
public TrackedFile(ILog log, string filename, string label)
|
2023-09-11 08:43:27 +00:00
|
|
|
|
{
|
|
|
|
|
this.log = log;
|
|
|
|
|
Filename = filename;
|
|
|
|
|
Label = label;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string Filename { get; }
|
|
|
|
|
public string Label { get; }
|
|
|
|
|
|
2023-09-12 11:32:06 +00:00
|
|
|
|
public void AssertIsEqual(TrackedFile? actual)
|
2023-09-11 08:43:27 +00:00
|
|
|
|
{
|
|
|
|
|
var sw = Stopwatch.Begin(log);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
AssertEqual(actual);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
2023-09-12 11:32:06 +00:00
|
|
|
|
sw.End($"{nameof(TrackedFile)}.{nameof(AssertIsEqual)}");
|
2023-09-11 08:43:27 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string Describe()
|
|
|
|
|
{
|
|
|
|
|
var sizePostfix = $" ({Formatter.FormatByteSize(GetFileSize())})";
|
|
|
|
|
if (!string.IsNullOrEmpty(Label)) return Label + sizePostfix;
|
|
|
|
|
return $"'{Filename}'{sizePostfix}";
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-12 11:32:06 +00:00
|
|
|
|
private void AssertEqual(TrackedFile? actual)
|
2023-09-11 08:43:27 +00:00
|
|
|
|
{
|
|
|
|
|
if (actual == null) Assert.Fail("TestFile is null.");
|
|
|
|
|
if (actual == this || actual!.Filename == Filename) Assert.Fail("TestFile is compared to itself.");
|
|
|
|
|
|
|
|
|
|
Assert.That(actual.GetFileSize(), Is.EqualTo(GetFileSize()), "Files are not of equal length.");
|
|
|
|
|
|
|
|
|
|
using var streamExpected = new FileStream(Filename, FileMode.Open, FileAccess.Read);
|
|
|
|
|
using var streamActual = new FileStream(actual.Filename, FileMode.Open, FileAccess.Read);
|
|
|
|
|
|
|
|
|
|
var bytesExpected = new byte[FileManager.ChunkSize];
|
|
|
|
|
var bytesActual = new byte[FileManager.ChunkSize];
|
|
|
|
|
|
|
|
|
|
var readExpected = 0;
|
|
|
|
|
var readActual = 0;
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
readExpected = streamExpected.Read(bytesExpected, 0, FileManager.ChunkSize);
|
|
|
|
|
readActual = streamActual.Read(bytesActual, 0, FileManager.ChunkSize);
|
|
|
|
|
|
|
|
|
|
if (readExpected == 0 && readActual == 0)
|
|
|
|
|
{
|
|
|
|
|
log.Log($"OK: '{Describe()}' is equal to '{actual.Describe()}'.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Assert.That(readActual, Is.EqualTo(readExpected), "Unable to read buffers of equal length.");
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < readActual; i++)
|
|
|
|
|
{
|
|
|
|
|
if (bytesExpected[i] != bytesActual[i]) Assert.Fail("File contents not equal.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long GetFileSize()
|
|
|
|
|
{
|
|
|
|
|
var info = new FileInfo(Filename);
|
|
|
|
|
return info.Length;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|