-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathXisoFileShareTests.cs
More file actions
133 lines (112 loc) · 4.49 KB
/
Copy pathXisoFileShareTests.cs
File metadata and controls
133 lines (112 loc) · 4.49 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using XISOSharp.Models;
namespace XISOSharp.Tests;
/// <summary>
/// File-share control (2.4): <c>OpenImageStream(path, FileShare)</c> and
/// <c>XisoExplorerOptions.Share</c> must let a mount coexist with a writer —
/// a handle open for write with <see cref="FileShare.Write"/> blocks the old
/// <see cref="FileShare.Read"/> default but not <see cref="FileShare.ReadWrite"/>.
/// </summary>
[Collection("Sequential")]
public sealed class XisoFileShareTests : IDisposable
{
private readonly List<string> _tempDirs = [];
public void Dispose()
{
foreach (string dir in _tempDirs)
{
try
{
if (Directory.Exists(dir)) Directory.Delete(dir, true);
}
catch
{
// ignored
}
}
}
private string CreateTempDir(string prefix)
{
string dir = Path.Combine(Path.GetTempPath(), $"{prefix}_{Guid.NewGuid():N}");
Directory.CreateDirectory(dir);
_tempDirs.Add(dir);
return dir;
}
private string CreateIso()
{
string src = CreateTempDir("xiso_share_src");
File.WriteAllText(Path.Combine(src, "readme.txt"), "shared image");
File.WriteAllText(Path.Combine(src, "data.bin"), new string('y', 5000));
string outDir = CreateTempDir("xiso_share_iso");
int result = XisoWriter.CreateXiso(src, outDir, null, null, out string? isoPath, null, null);
Assert.Equal(0, result);
Assert.NotNull(isoPath);
return isoPath;
}
/// <summary>
/// Holds a write-capable handle that denies other writers but shares reads:
/// the same shape an AV scanner or sync client takes on a mounted .iso.
/// </summary>
private static FileStream HoldWriterHandle(string iso) =>
new(iso, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
[Fact]
public void OpenImageStream_ReadWriteShare_OpensWhileWriterHoldsFile()
{
string iso = CreateIso();
using FileStream writer = HoldWriterHandle(iso);
using Stream stream = XisoReader.OpenImageStream(iso, FileShare.ReadWrite);
Assert.True(XisoReader.GetVolumeInfo(stream, iso).IsValid);
}
[Fact]
public void OpenImageStream_DefaultShare_FailsWhileWriterHoldsFile()
{
string iso = CreateIso();
using FileStream writer = HoldWriterHandle(iso);
// The 1.0.2 default stays FileShare.Read: a mounted image whose writer
// denies sharing still blocks the open, by design.
Assert.Throws<IOException>(() => XisoReader.OpenImageStream(iso));
}
[Fact]
public void Explorer_ShareReadWrite_OpensAndReadsWhileWriterHoldsFile()
{
string iso = CreateIso();
using FileStream writer = HoldWriterHandle(iso);
using XisoExplorer explorer = new(iso, new XisoExplorerOptions
{
KeepOpen = true,
Share = FileShare.ReadWrite,
});
Assert.Equal(2, explorer.ListChildren("/").Count);
using Stream readme = explorer.OpenReadStream("/readme.txt");
using MemoryStream copy = new();
readme.CopyTo(copy);
Assert.Equal("shared image", System.Text.Encoding.ASCII.GetString(copy.ToArray()));
}
[Fact]
public void Explorer_DefaultShare_FailsWhileWriterHoldsFile()
{
string iso = CreateIso();
using FileStream writer = HoldWriterHandle(iso);
Assert.Throws<IOException>(() => new XisoExplorer(iso));
}
[Fact]
public void Explorer_ShareReadWrite_StatelessOpenReadStreamWorksWhileWriterHoldsFile()
{
string iso = CreateIso();
using FileStream writer = HoldWriterHandle(iso);
using XisoExplorer explorer = new(iso, new XisoExplorerOptions { Share = FileShare.ReadWrite });
using Stream readme = explorer.OpenReadStream("/readme.txt");
using MemoryStream copy = new();
readme.CopyTo(copy);
Assert.Equal("shared image", System.Text.Encoding.ASCII.GetString(copy.ToArray()));
}
[Fact]
public void Ciso_ShareReadWrite_OpensWhileWriterHoldsContainer()
{
string iso = CreateIso();
string cso = Path.Combine(Path.GetDirectoryName(iso)!, "game.cso");
Assert.Equal(0, CisoWriter.CompressToCso(iso, cso, level: 0));
using FileStream writer = new(cso, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
using Stream stream = XisoReader.OpenImageStream(cso, FileShare.ReadWrite);
Assert.True(XisoReader.GetVolumeInfo(stream, cso).IsValid);
}
}