/ Framework / FileUtils / TrackedFile.cs
TrackedFile.cs
 1  using Logging;
 2  using Utils;
 3  
 4  namespace FileUtils
 5  {
 6      public class TrackedFile
 7      {
 8          private readonly ILog log;
 9  
10          public TrackedFile(ILog log, string filename, string label)
11          {
12              this.log = log;
13              Filename = filename;
14              Label = label;
15          }
16  
17          public static TrackedFile FromPath(ILog log, string filepath)
18          {
19              // todo: I don't wanne have to do this to call upload.
20              return new TrackedFile(log, filepath, string.Empty);
21          }
22  
23          public string Filename { get; }
24          public string Label { get; }
25  
26          public void AssertIsEqual(TrackedFile? actual)
27          {
28              var sw = Stopwatch.Begin(log);
29              try
30              {
31                  AssertEqual(actual);
32              }
33              finally
34              {
35                  sw.End($"{nameof(TrackedFile)}.{nameof(AssertIsEqual)}");
36              }
37          }
38  
39          public string Describe()
40          {
41              var sizePostfix = $" ({Formatter.FormatByteSize(GetFileSize())})";
42              if (!string.IsNullOrEmpty(Label)) return Label + sizePostfix;
43              return $"'{Filename}'{sizePostfix}";
44          }
45  
46          public ByteSize GetFilesize()
47          {
48              return new ByteSize(GetFileSize());
49          }
50  
51          private void AssertEqual(TrackedFile? actual)
52          {
53              if (actual == null)  FrameworkAssert.Fail("TestFile is null.");
54              if (actual == this || actual!.Filename == Filename) FrameworkAssert.Fail("TestFile is compared to itself.");
55  
56              FrameworkAssert.That(actual.GetFileSize() == GetFileSize(), "Files are not of equal length.");
57  
58              using var streamExpected = new FileStream(Filename, FileMode.Open, FileAccess.Read);
59              using var streamActual = new FileStream(actual.Filename, FileMode.Open, FileAccess.Read);
60  
61              var bytesExpected = new byte[FileManager.ChunkSize];
62              var bytesActual = new byte[FileManager.ChunkSize];
63  
64              var readExpected = 0;
65              var readActual = 0;
66  
67              while (true)
68              {
69                  readExpected = streamExpected.Read(bytesExpected, 0, FileManager.ChunkSize);
70                  readActual = streamActual.Read(bytesActual, 0, FileManager.ChunkSize);
71  
72                  if (readExpected == 0 && readActual == 0)
73                  {
74                      log.Log($"OK: {Describe()} is equal to {actual.Describe()}.");
75                      return;
76                  }
77  
78                  FrameworkAssert.That(readActual == readExpected, "Unable to read buffers of equal length.");
79  
80                  for (var i = 0; i < readActual; i++)
81                  {
82                      if (bytesExpected[i] != bytesActual[i]) FrameworkAssert.Fail("File contents not equal.");
83                  }
84              }
85          }
86  
87          private long GetFileSize()
88          {
89              var info = new FileInfo(Filename);
90              return info.Length;
91          }
92      }
93  }