Repository navigation
Expand file tree
/
Copy pathSparseOutputTests.cs
More file actions
105 lines (90 loc) · 3.47 KB
/
Copy pathSparseOutputTests.cs
File metadata and controls
105 lines (90 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
namespace XISOSharp.Tests;
/// <summary>
/// LIB-03: pre-sized outputs are marked sparse where the file system supports
/// it, and the existing extraction/compression paths still round-trip.
/// </summary>
[Collection("Sequential")]
public sealed class SparseOutputTests : IDisposable
{
private readonly List<string> _tempDirs = [];
public void Dispose()
{
foreach (string dir in _tempDirs)
{
try
{
if (Directory.Exists(dir)) Directory.Delete(dir, true);
}
catch
{
// Best effort.
}
}
}
[RequiresNtfsFact]
public void Prepare_PreSizesWithoutAllocatingTheWholeRange()
{
string path = Path.Combine(CreateTempDir(), "large.bin");
const long length = 128L * 1024 * 1024;
using (FileStream stream = new(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
{
SparseFile.Prepare(stream, length);
Assert.Equal(length, stream.Length);
stream.WriteByte(0x42);
long allocated = SparseFile.GetAllocatedSize(stream);
Assert.True(allocated >= 0, "Windows should report the allocation size.");
Assert.True(allocated < length / 4,
$"Expected a sparse allocation below {length / 4} bytes, got {allocated}.");
}
Assert.Equal(length, new FileInfo(path).Length);
Assert.Equal(0x42, File.ReadAllBytes(path)[0]);
}
[RequiresNtfsFact]
public void LocalFilesystem_ExpectedLength_IsSparse()
{
string root = CreateTempDir();
LocalFilesystem filesystem = new(root);
const long length = 64L * 1024 * 1024;
using (Stream stream = filesystem.CreateFile("file.bin", length))
{
Assert.Equal(length, stream.Length);
stream.WriteByte(1);
if (stream is FileStream fileStream)
{
long allocated = SparseFile.GetAllocatedSize(fileStream);
Assert.True(allocated >= 0);
Assert.True(allocated < length / 4,
$"Expected a sparse allocation below {length / 4} bytes, got {allocated}.");
}
}
}
[Fact]
public void CisoDecompress_ZeroHeavyImage_RoundTrips()
{
string work = CreateTempDir();
string source = Path.Combine(work, "src");
Directory.CreateDirectory(source);
File.WriteAllText(Path.Combine(source, "readme.txt"), "zeros\n");
byte[] zeros = new byte[512 * 1024];
File.WriteAllBytes(Path.Combine(source, "zeros.bin"), zeros);
string iso = Path.Combine(work, "image.iso");
Assert.Equal(0, XisoWriter.PackFromDirectory(source, iso, fileTime: 0));
string cso = Path.Combine(work, "image.cso");
Assert.Equal(0, CisoWriter.CompressToCso(iso, cso, level: 1));
string extracted = Path.Combine(work, "extracted.iso");
Assert.Equal(0, CisoReader.DecompressToIso(cso, extracted));
Assert.Equal(Sha256(iso), Sha256(extracted));
}
private string CreateTempDir()
{
string dir = Path.Combine(Path.GetTempPath(), $"xiso_sparse_{Guid.NewGuid():N}");
Directory.CreateDirectory(dir);
_tempDirs.Add(dir);
return dir;
}
private static string Sha256(string path)
{
using FileStream stream = File.OpenRead(path);
return Convert.ToHexString(System.Security.Cryptography.SHA256.HashData(stream));
}
}